Могу ли я быть полностью уверен, что это ничего не сломает?
Нет. Вы меняете значение равенства со ссылочной идентичности на своего рода равенство значений. Вы сломаете все, полагаясь на текущее поведение. Например, вот какой-то действительный код:
Person person1 = new Person("Foo", 100);
Person person2 = new Person("Foo", 100);
// This is fine. Two distinct Person objects will never be equal...
if (person1.equals(person2)) {
launchNuclearMissiles();
}
Ваше предлагаемое изменение нарушит это.
У вас на самом деле есть такой код? Трудно сказать.
Скорее всего, если вы захотите изменить hashCode
на включение хэшей из List<Friend>
, вы можете очень легко разбить код, если тип не является неизменным. Например:
Map<Person, String> map = new HashMap<>();
Person person = new Person("Foo", 100);
map.put(person, "Some value");
// If this changes the result of hashCode()...
person.addFriend(new Friend("Bar"));
// ... then you may not be able to find even the same object in the map.
System.out.println(map.get(person));
По сути, вам необходимо знать, какой другой код использует Person
, чтобы вы знали, на что он опирается. Если Person
является неизменным, это делает жизнь намного проще, потому что вам не нужно беспокоиться о втором типе проблемы. (Переопределение equals()
и hashCode()
для изменчивых типов - дело крайне коварное.)