PDA

View Full Version : [JAVA] Comparable ed interi


cifa
24-05-2011, 17:27
Salve a tutti ho un piccolo problemino, per utilità mi son creato una classe
public class ListaOrdinata<Chiave, Valore>

che utilizzo sia con <String, Valore> che con <Integer, Valore>. Con String va tutto bene, ma con gli Integer agisce come se i numeri a singola cifra fossero > di quelli a doppia cifra.

Ecco i metodi che uso per l'insert "ordinato"

public boolean minore(Nodo<K,V> nodo) {
return minore(nodo.chiave, chiave);
}

public boolean minore(K k1, K k2) {
if (k1 == null) return false;
if (k2 == null) return true;
return (k1.toString().compareTo(k2.toString()) < 0 );
}







public void insert(Chiave k, Valore v) {
testa = insert(k, v, testa);
}

private Nodo<Chiave,Valore> insert(Chiave k, Valore el, Nodo<Chiave,Valore> testa) {

// caso 1: la lista e' vuota
if (testa == null)
return new Nodo<Chiave,Valore>(k,el);


// caso 2: la chiave e' maggiore del primo elemento e un nuovo nodo va inserito prima
if (testa.minore(k,testa.chiave)) {
Nodo<Chiave,Valore> nuovo = new Nodo<Chiave,Valore>(k,el);
nuovo.prox = testa;
return nuovo;
}

// caso 3: l'elemento va inserito nel resto della lista
testa.prox = insert(k, el, testa.prox);
return testa;
}


Come posso risolvere ?

Vi ringrazio :)

PGI-Bis
24-05-2011, 17:53
Il problema è che il PC non è abbastanza intelligente per capire da solo che se una stringa contiene un numero allora potresti volerlo ordinare per la quantità che esprime anziché per la sequenza di caratteri da cui è composto.

Detto altrimenti,

"10" > "9.5" ? no perché il carattere "1" vale meno del carattere "9"
10 > 9.5? sì perché 10 è maggiore di 9.5

Posto che si tratta di un problema già risolto nelle librerie standard, l'intoppo si aggirerebbe "parametrizzando" il confronto che fai nel metodo "minore", vale a dire considerando che tipi di dato diversi possono richiedere funzioni d'ordine diverse.

Dovresti cioè dire: se k1 e k2 esprimono dei numeri allora non uso un ordinamento lessicografico ma userò un ordinamento numerico, considerandoli come numeri (cioè li converti a Long o Double secondo i casi).

Da lì ti accorgerai che ci sono casi che richiedono un tanto di arbitrarietà: ad esempio una stringa e un numero o un JPanel e un Point. Come li ordini? Be', come preferisci.

cifa
24-05-2011, 18:34
Il problema è che il PC non è abbastanza intelligente per capire da solo che se una stringa contiene un numero allora potresti volerlo ordinare per la quantità che esprime anziché per la sequenza di caratteri da cui è composto.

Detto altrimenti,

"10" > "9.5" ? no perché il carattere "1" vale meno del carattere "9"
10 > 9.5? sì perché 10 è maggiore di 9.5

Posto che si tratta di un problema già risolto nelle librerie standard, l'intoppo si aggirerebbe "parametrizzando" il confronto che fai nel metodo "minore", vale a dire considerando che tipi di dato diversi possono richiedere funzioni d'ordine diverse.

Dovresti cioè dire: se k1 e k2 esprimono dei numeri allora non uso un ordinamento lessicografico ma userò un ordinamento numerico, considerandoli come numeri (cioè li converti a Long o Double secondo i casi).

Da lì ti accorgerai che ci sono casi che richiedono un tanto di arbitrarietà: ad esempio una stringa e un numero o un JPanel e un Point. Come li ordini? Be', come preferisci.

Chiarissimo, grazie mille :)

WarDuck
24-05-2011, 19:10
Non basterebbe evitare di usare il toString() in minore?

compareTo dovrebbe già includere queste cose, altrimenti a che servono le interfacce? :D

cifa
24-05-2011, 20:11
Non basterebbe evitare di usare il toString() in minore?

compareTo dovrebbe già includere queste cose, altrimenti a che servono le interfacce? :D

Eh no perchè compareTo potrebbe non esser definitio in K :\

Don[ITA]
24-05-2011, 20:36
Puoi dichiarare la tua chiave come Comparable, o come K extends Comparable, così sei certo che la tua chiave implementi il metodo compareTo :)

cifa
24-05-2011, 20:42
;35227013']Puoi dichiarare la tua chiave come Comparable, o come K extends Comparable, così sei certo che la tua chiave implementi il metodo compareTo :)

Scusa la domanda, ma sono nuovo di Java ^^

Quindi dovrei fare una cosa del genere ?
public class ListaOrdinata<Chiave extends Comparable, Valore>

?

PGI-Bis
24-05-2011, 22:04
Puoi usare TreeMap, che è già incluso nelle librerie standard e funziona allo stesso modo.

Opzione che probabilmente risulterà allettante se consideri che la forma suggerita sarebbe precisamente:

public class SortedList<K extends Comparable<? super K>, V> {

La ragione sta nelle 297 pagine dei Java Generics FAQ.

cifa
24-05-2011, 22:51
Puoi usare TreeMap, che è già incluso nelle librerie standard e funziona allo stesso modo.

Opzione che probabilmente risulterà allettante se consideri che la forma suggerita sarebbe precisamente:

public class SortedList<K extends Comparable<? super K>, V> {

La ragione sta nelle 297 pagine dei Java Generics FAQ.

Ti ringrazio, anche se tutto questo fa parte di un progetto universitario e non avendo ancora fatto alberi e mappe forse è meglio non utilizzarli. In ogni caso per curiosità personale vado a studiarmi TreeMap :)