Capire con un programma la differenza tra TreeSet e HashSet

di il
2 risposte

Capire con un programma la differenza tra TreeSet e HashSet

Buongiorno.

Mi viene proposto un esercizio per comprendere l'uso TreeSet<T> e HashSet<T>.
Ci sono quasi arrivato pero' ho qualche dubbio.

L'esercizio e' il seguente:

/* Obiettivo: comprensione uso TreeSet<T> e HashSet<T>

- cosa stampa questo programma? perche'?

- compilare

- eseguire il programma e verificare la propria risposta
*/

import java.util.*;

class Libro implements Comparable<Libro> {
private int anno;
private String titolo;

Libro(int anno, String titolo) {
this.anno = anno;
this.titolo = titolo;
}

public int hashCode() {
return (this.anno + this.titolo.hashCode());
}

public int compareTo(Libro libro) {
return this.anno - libro.getAnno();
}

public String getTitolo() {
return this.titolo;
}

public int getAnno() {
return this.anno;
}

public boolean equals(Object o) {
Libro l = (Libro) o;
return ((this.anno == l.getAnno()) &&
(this.titolo.equals(l.getTitolo())));
}
}

public class ProveTreeSet {

public static void main(String[] argv) {
Set<Libro> set1 = new TreeSet<Libro>();
Libro l1 = new Libro(2000,"Ieri e oggi");
Libro l2 = new Libro(2000, "Domani e dopodomani");
set1.add(l1);
set1.add(l2);

Set<Libro> set2 = new HashSet<Libro>();
set2.add(l1);
set2.add(l2);

System.out.println("set1.size()="+set1.size());
System.out.println("set2.size()="+set2.size());
}
}

Ho compilato il programma e il risultato e' il seguente :
run:
set1.size()=1
set2.size()=2
BUILD SUCCESSFUL (total time: 0 seconds)


Mi dite se quello che sto' per scrivere secondo voi e' corretto ?

Prima di tutto vengono confrontati i campi anno e titolo in questo metodo , restituendo un valore booleano

public boolean equals(Object o) {
Libro l = (Libro) o;
return ((this.anno == l.getAnno()) &&
(this.titolo.equals(l.getTitolo())));
}


Ho notato che se cambio il valore di l1 e di l2 mettendo le stesse informazioni sia per l1 che per l2 ,

Libro l1 = new Libro(2000,"Ieri e oggi");
Libro l2 = new Libro(2000, "Domani e dopodomani");

Libro l1 = new Libro(2000,"Ieri e oggi");
Libro l2 = new Libro(2000, "Ieri e oggi");

il risultato diventa :

set1.size()=1
set2.size()=1

Se cambio il solo valore intero per esempio 2000 e 2001 e lascio la stringa non uguale ,

Libro l1 = new Libro(2000,"Ieri e oggi");
Libro l2 = new Libro(2001, "Domani e dopodomani");

il risultato sara' :

set1.size()=2
set2.size()=2


Da questo dovrei capire la differenza tra HashSet e TreeSet
pero' ancora non ci sono .
Secondo me queste due funzioni nascondo qualche altro segreto oltre al fatto di confrontare un campo stringa e un campo intero.
C'e' qualcosa che mi sfugge .
Magari se potete farmi capire bene il concetto con qualche esempio , ve ne sarei grato ..

2 Risposte

  • Re: Capire con un programma la differenza tra TreeSet e HashSet

    FabioJ ha scritto:


    Mi viene proposto un esercizio per comprendere l'uso TreeSet<T> e HashSet<T>.
    Ci sono quasi arrivato pero' ho qualche dubbio.

    Da questo dovrei capire la differenza tra HashSet e TreeSet
    pero' ancora non ci sono .
    TreeSet è basato internamente su un albero binario e mantiene ordinati gli elementi basandosi sul contenuto degli oggetti stessi. TreeSet si basa SOLO sul compareTo (Comparable) oppure compare (Comparator). Insomma, NON usa equals/hashCode.

    HashSet è basato internamente su una hash-table e pertanto usa SOLO equals/hashCode.

    Il punto è che nel tuo Libro equals/hashCode usano anno E titolo mentre il compareTo usa solo l'anno !! Questo vuol dire che per TreeSet i due oggetti sono "uguali" e questo è il motivo per cui vedi

    set1.size()=1


    P.S. solo due note:
    - il hashCode() è tecnicamente corretto ma si può migliorare sulla distribuzione dei codici.
    - in equals() il cast diretto NON va bene in generale. Bisogna sempre prima testare il tipo.
  • Re: Capire con un programma la differenza tra TreeSet e HashSet

    Grazie.
Devi accedere o registrarti per scrivere nel forum
2 risposte