Обычно я не код на Java, но в последнее время у меня не было выбора. Возможно, у меня возникло серьезное непонимание того, как правильно использовать HashSet. Таким образом, возможно, что-то, что я сделал, просто неправильно. Однако я благодарен за любую помощь, которую вы могли бы предложить. Таким образом, актуальная проблема:Java Hashset.contains() производит таинственный результат
В небольшой программе, которую я писал, я создавал очень похожие объекты, которые при создании имели бы очень специфический идентификатор (string
или в моей последней итерации long
). Поскольку каждый объект создавал новые объекты, я хотел отфильтровать все те, что я уже создал. Поэтому я начал бросать id каждого нового объекта в свой Hash (Set) и тестирование с HashSet.contains()
, если ранее был создан объект. Вот полный код:
// 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());
}
}
производит следующий вывод:
true
false
true
true
так, по-видимому, contains
не использует функцию equals
предоставленную L
, или у меня есть некоторые основные непонимание концепции ...
Я тестировал его с помощью openjdk (текущая версия, включенная в ubuntu) и официальная текущая Java из Oracle на Win7
для полноты официальной документации Java-API для HashSet.contains()
:
public boolean contains(Object o)
Возвращает
true
, если этот набор содержит указанный элемент. Более формально возвращаетtrue
тогда и только тогда, когда этот набор содержит элементe
такой, что(o==null ? e==null : o.equals(e))
.
http://download.oracle.com/javase/6/docs/api/java/util/HashSet.html#contains(java.lang.Object)
Любые идеи или предложения?
Чтобы уточнить - если у вас нет подписи вашей версии «равно», вы фактически не перегружаете равные, а HashSet (и все остальное) будет использовать исходный метод equals, если он напрямую не знает о классе L (как и ваш тестовый код). Чтобы проверить это, добавьте: System.out.println (a.equals ((Object) b)); к вашей тестовой программе - он должен вернуть значение false. –