Как часть Hadoop Mapper
, у меня есть HashSet<MySimpleObject>
, который содержит экземпляры очень простого класса только с двумя целочисленными атрибутами. Как и положено, я настроил hashCode()
и equals()
:
public class MySimpleObject {
private int i1, i2;
public set(int i1, int i2) {
this.i1 = i1;
this.i2 = i2;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + i1;
result = prime * result + i2;
return result;
}
@Override
public boolean equals(Object obj) {
if (obj == null) return false;
if (this == obj) return true;
if ( obj.getClass() != MySimpleObject.class ) return false;
MySimpleObject other = (MySimpleObject)obj;
return (this.i1 == other.i1) && (this.i2 == other.i2);
}
Иногда каким-то образом вызовы mySet.contains(aSimpleObj)
возвращают true
, хотя набор на самом деле не содержит этого значения.
Я понимаю, что hashCode()
сначала используется для разделения экземпляров на сегменты, а equals()
вызывается только для сравнения экземпляров внутри данного сегмента.
Я пытался изменить простое значение в hasCode()
, чтобы по-разному распределять экземпляры по сегментам, и увидел, что contains()
все еще иногда вернул неправильный результат, но не для того же ранее ошибочного значения.
Также кажется, что это значение было затем правильно идентифицировано как выходящее за пределы набора; Поэтому я подозреваю, что что-то не так с проверкой на равенство, а не с хешированием, но я могу ошибаться...
Я в полной растерянности, и у меня нет идей. Может ли кто-нибудь пролить свет на это вообще?
----- изменить -----
некоторые пояснения:
i1
иi2
никогда не обновляются после построения для экземпляров, которые были добавлены в набор (хотя они иногда обновляются в другом месте кода для других экземпляров того же класса);- набор потенциально довольно велик (т.е. может достигать почти 15 тыс. записей), и мне интересно, может ли проблема быть связана с этим (например, переполнение ведра?).
i1
иi2
для объектов, уже содержащихся в вашем HashSet? - person Eran   schedule 19.03.2018i1
иi2
после добавления объектов в набор? - person Alexandre Dupriez   schedule 19.03.2018contains()
возвращает значение true, когда оно должно возвращать значение false. В нынешнем виде я не могу воспроизвести ваш результат. - person Daniel Pryden   schedule 19.03.2018obj.getClass() != MySimpleObject.class
, он не будет управлять подклассами. Вместо этого используйтеinstanceof
. - person AxelH   schedule 19.03.2018result =result+ prime * result + i1;
но лучше использоватьObjects.hashCode()
- person dehasi   schedule 19.03.2018Object
hashCode()
возвращает ссылку на экземпляр и, следовательно, может отличаться для двух экземпляров с одинаковыми значениями (чего не должно быть) - person J. Doe   schedule 19.03.2018Objects.hash()
извините за введение в заблуждение. - person dehasi   schedule 19.03.2018WritableComparable
- person OneCricketeer   schedule 19.03.2018hashCode()
не используется Hadoop (я имею в виду javadoc дляWritableComparable
: Обратите внимание, что hashCode() часто используется в Hadoop для разделения ключей.); хотя на самом деле эта проблема исчезает, когда я пытаюсь воспроизвести ее в локальной подпрограмме, а не вMapper
. Однако я импортируюjava.util.HashSet
, поэтому я верю, что хэш-значения поступают изhashcode()
. - person J. Doe   schedule 19.03.2018