Di solito non codice in Java, ma di recente non ho iniziato a scegliere. Potrei avere qualche grosso malinteso su come utilizzare correttamente HashSet. Quindi potrebbe essere possibile che qualcosa che ho fatto sia semplicemente sbagliato. Comunque sono grato per qualsiasi aiuto, potresti offrire. Quindi il problema reale:Java Hashset.contains() produce un risultato misterioso
In un piccolo programma stavo scrivendo, stavo generando oggetti molto simili, che, una volta creati, avrebbero un ID molto specifico (a long
). Poiché ogni oggetto generava nuovi oggetti, volevo filtrare tutti quelli che ho già creato. Così ho iniziato a lanciare l'id di ogni nuovo oggetto nel mio Hash (Set) e testare con HashSet.contains()
, se un oggetto è stato creato prima. Ecco il codice completo:
// hashtest.java
import java.util.HashSet;
class L {
public long l;
public L(long l) {
this.l = l;
}
public int hashCode() {
return (int)this.l;
}
public boolean equals(L other) {
return (int)this.l == (int)other.l;
}
}
class hashtest {
public static void main(String args[]) {
HashSet<L> hash = new HashSet<L>();
L a = new L(2);
L b = new L(2);
hash.add(a);
System.out.println(hash.contains(a));
System.out.println(hash.contains(b));
System.out.println(a.equals(b));
System.out.println(a.hashCode() == b.hashCode());
}
}
produce output seguente:
true
false
true
true
così apparentemente, contains
non utilizza la funzione equals
fornito da L
, o ho qualche grande malinteso del concetto ...
L'ho provato con openjdk (versione corrente inclusa in ubuntu) e il java corrente ufficiale da Oracle su Win7
per completezza documentazione ufficiale API Java per HashSet.contains()
:
public boolean contains(Object o)
Restituisce
true
se questo insieme contiene l'elemento specificato . Più formalmente, restituiscetrue
se e solo se questo set contiene un elementoe
tale che(o==null ? e==null : o.equals(e))
.
http://download.oracle.com/javase/6/docs/api/java/util/HashSet.html#contains(java.lang.Object)
Tutte le idee o suggerimenti?
Per chiarire - se non si ha la firma della propria versione di "uguale", allora non si sta effettivamente sovraccaricando equals, e HashSet (e qualsiasi altra cosa) useranno il metodo originale equals a meno che non sappia direttamente sulla classe L (come fa il tuo codice di prova). Per verificare ciò, aggiungere: System.out.println (a.equals ((Object) b)); al tuo programma di test - dovrebbe restituire false. –