2016-09-09 1 views
2

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

public class DualKey { 
    int key1; 
    int key2; 
    // getters, setters and constructors go here 
    public void equals(Object obj) { 
     if (obj == null || ! obj instanceOf DualKey) 
      return false; 
     return this.key1 == obj.key1 || this.key1 == obj.key2 || this.key2 == obj.key1 || this.key2 == obj.key2; 
    } 

} 

Можно ли переопределить хэш-код таким образом, что сохраняется контракт равно и хэш-код?

PS: Я понимаю, что было бы лучше определить компаратор вместо этого, но я работаю с искре, где единственный способ определить равенство - это переопределить метод equals.

+0

Нет, с вашей фактической настройкой это невозможно (если только вы не вернете '0', который сохранит контракт,« если он равен, то и hashcode должен быть равен », но у вас будет тонна столкновений) – tkausl

ответ

6

Нет, это не представляется возможным, потому что equals() реализация не отвечает требованиям API в Java:

Равных метод реализует отношение эквивалентности ссылок непустых объекта:

  • Это reflexive: для любого ненулевого эталонного значения x, x.equals(x) должно возвращать true.
  • Это симметричный: для любых ненулевых эталонных значений x и y, x.equals(y) должен возвращать true тогда и только тогда, когда y.equals(x) возвращается true.
  • Это транзитивное: для любых ненулевых эталонных значений x, y и z, если x.equals(y) возвращает true и y.equals(z) возвращает true, то x.equals(z) должен возвращать true.
  • Это соответствует: для любых ненулевых эталонных значений x и y, несколько призываний x.equals(y) последовательно возвращать true или последовательно возвращать false, не представили никакой информации, используемой в equals сравнений на объектах модифицируется.
  • Для любого ненулевого опорного значения x, x.equals(null) должен возвращать false.

В частности, это не транзитивно. С вашим определением (1,2) == (2,3) и (2,3) == (3,4), но (1,2) != (3,4).

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

Смежные вопросы