Newsgroup: it.comp.java
Titolo: Metodo equals(): ma quando viene interpellato ?

Tempo fa avevo iniziato un interessante discussione sul metodo
equals() con Fabrizio Camera che vorrei riprendere per parlare di un
comportamento per me inspiegabile.
Riassunto dei post precedenti: 
volevo realizzare una classe che rappresentasse una pagina web con i
link in essa contenuti. Ho pensato cosě di estendere una classe
HashSet e mettere un bel campo privato String che rappresentasse l'url
della pagina.
Dopodichč ho dovuto sovrascrivere il metodo equals() per assicurare il
corretto funzionamento del metodo add(Object) invocato per aggiungere
l'oggetto WebPage in una Collection.
A questo punto Fabrizio mi ha fatto notare che la rappresentazione
della pagina corrisponde meglio al paradigma "pagina web contiene una
lista di link" piuttosto che "č una lista di link".
Convenendo, ho modificato la classe che non č un'estensione di
HashSet, ma contiene un hashSet.
E qui si č presentato un nuovo problema: provando a raccogliere gli
oggetti istanze di WebPage in una collezione ho notato che il metodo
equals() non funziona piů.
Leggendo le API della classe Object mi č capitata sotto gli occhi la
riga:
"Note that it is generally necessary to override the hashCode method
whenever this method is overridden, so as to maintain the general
contract for the hashCode method, which states that equal objects must
have equal hash codes."
Quindi due oggetti sono uguali se hanno un hashCode uguale , ma perchč
nel primo caso estendo la classe HashSet non c'č stato bisogno di fare
l'override del metodo HashCode ?
Con l'override del metodo hashCode() tutto funziona.
Mi sono dilungato un po', ma la cosa non mi sembra molto semplice.
Di seguito metto il codice dei metodi che ho "overraddato" ;-)
 // ridefinisco il metodo equals
    public int hashCode(){
    	return url.hashCode();
    }
    // ridefinisco il metodo equals
    public boolean equals(Object o) {
        if ( o != null && getClass() == o.getClass() ) {
            WebPage wp = (WebPage)o;
            return url.equals(wp.url);
        }
        else {
            return false;
        }
    }

 
Non ho capito bene il fenomeno da te descritto, ma ...
Nel primo caso, quando estendi HashSet, hai in regalo l'implementazione 
di hashCode ereditata da AbstractSet, chè è implementata sommando gli 
hashcode di tutti gli elementi non null presenti nel set.
Nel secondo ovviamente devi implementare tu il metodo hashCode, 
altrimenti hai quello ereditato da Object che, se non ricordo male, 
restituisce la rappresentazione come intero dell'indirizzo di memoria 
(relativamente alla JVM).
In generale equals viene utilizzato per confrontare due oggetti e 
hashCode per ottenere appunto un codice hash da utilizzare in una hashtable.
Un Vector utilizzerà equals per trovare un oggetto con indexOf, mentre 
una HashMap userà l'hashCode dell'oggetto che passi come chiave per 
"indicizzare" la sua struttura interna (bucket-list o array o quello che 
vuoi).
Ciao
-- 
Fabio Ambrosanio
/quousque tandem/

 (relativamente alla JVM).
Confermo.
Ciao, Luigi
-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com
 - The #1 Newsgroup Service in the World!
-----==  Over 80,000 Newsgroups - 16 Different Servers! =-----


Grazie. 
Luigi