2016-12-12 1 views
-2

Я использую построитель хеш-кода как переменную экземпляра pojo.Apache Commons hashCode builder несогласованные хэши

public class Pojo { 
private HashCodeBuilder hashBuilder = new HashCodeBuilder(); 
private int i; 
public setI(int i) {this.i = i} 

@Override 
public int hashCode() {   
    hashBuilder.append(id);   
    return hashBuilder.toHashCode(); 
} 
} 

Теперь, если я установить значение i на ту же величину в два раза, то мой результат хэш-код будет отличаться. Это ошибка в реализации?

Я понимаю, что это происходит из-за того, что построитель хеш-кода сохраняет текущую сумму. Но должен ли он не давать один и тот же хэш для одного и того же набора значений?

Кроме того, если я не следовать выше подходу, то я буду в конечном итоге инициализацией же хэш-код строителя в hashcode методы моих Pojo тысячи раз следующим образом:

... 
@Override 
public int hashCode() { 
    hashBuilder = new HashBuilder();   
    hashBuilder.append(id);   
    return hashBuilder.toHashCode(); 
} 
... 

Есть ли способ чтобы сбросить эту текущую итоговую так, чтобы каждый раз, когда я вызываю hashcode с тем же набором значений, я получаю согласованный ответ?

+0

И почему сброс будет более эффективным, чем создание нового экземпляра? Вы не должны повторно использовать его, в первую очередь, imho. Он даже сбой с одним и тем же идентификатором и вызовом 'hashCode' дважды подряд. –

+0

ну, вы создаете одно pojo, а затем в конечном итоге вызываете hashcode 'X' количество раз. В итоге вы создадите объекты построения хеш-кода 'X', которые потенциально собираются собирать мусор, но вы никогда не знаете, когда это произойдет. Таким образом, до этого времени ваше использование памяти увеличивается. Поэтому я думаю, что лучше иметь только одно pojo? – sttaq

+0

НЕТ это не так. Особенно не с короткоживущими объектами, они приходят более или менее бесплатно. Они довольно быстро. Похоже на преждевременную оптимизацию, а не на реальную меру. –

ответ

1

Как вы это делаете, вы добавляете другой id каждый раз, когда вы вызываете hashCode(). Так как append() принимает значение (не имя поля!), То HashCodeBuilder не имеет возможности узнать, добавлено ли вы id или у вас есть другое поле, имеющее то же значение.

Создайте HashCodeBuilder локально в hashCode(). Не предполагайте, что это повлияет на производительность значительным образом, если вы не профилировали приложение и не доказали, что он делает (иначе избегайте преждевременной оптимизации).

Если вы действительно хотите, чтобы избежать ненужного создания HashCodeBuilder на каждом hashCode(), вам придется отслеживать изменения в инкубационных и установите hashCodeBuilder в null всякий раз, когда значение изменяется через сеттер; затем используйте его в hashCode(), если необходимо. Тогда вам нужно будет убедиться, что всякая модификация поля проходит через сеттеры. Довольно много работы, и многие вещи могут пойти не так, поэтому вы действительно хотите избежать всего этого, если это возможно.

+0

или простое решение было бы предоставить метод сброса в хэш-компоновщике? – sttaq

+0

Очевидно, что авторы библиотеки не видели никакой необходимости в таком методе. Создание экземпляра throwaway дешево на Java. Переменные экземпляра влияют на безопасность потоков. Обычное использование заключается только в том, чтобы сохранить экземпляр локально в 'hashCode()', и если вы хотите перейти к кешированию кеш-кода, вы бы лучше кэшировали полученный хеш-код, чем в любом случае сохраняли конструктор. –

+0

Обновление - я только что прочитал реализацию строителя, используется threadlocal, поэтому безопасность потоков не будет проблемой. –