[英]Can adding equals() and hashCode() method spoil something
添加equals()
和hashCode()
方法是否有可能破壞現有代碼?
我有一個包含 3 個字段、getter 和 setter 的類:
public class Person {
private final String name;
private final List<Friend> friends;
private final Integer age;
為了測試我使用的這個類: isEqualToComparingFieldByField()
方法來比較兩個Person
對象,而不是添加equals()
和hashCode()
。 其他解決方案是覆蓋equals()
和hashCode()
並使用assertEquals()
來比較這些對象,但我可以完全確定它不會破壞任何東西嗎?
我可以完全確定它不會破壞任何東西嗎?
不。您正在將相等的含義從引用標識更改為某種值相等。 你會破壞任何依賴於當前行為的東西。 例如,這里有一些有效的代碼:
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()
從根本上是一項危險的業務。)
這取決於您在何處以及如何使用 person 對象。 例如,如果您將 person 存儲在 HashSet、HashMap 等數據結構中,那么它的行為可能會有所不同。 但是,如果您使用任何使用哈希和等於的數據結構,總是建議覆蓋這些方法。
創建自定義類時,應始終覆蓋這些方法。 如果不這樣做,則使用 Object 類的實現,並且這些實現依賴於引用 - 而不是自定義類的對象中的字段值。
如果您創建自定義類的兩個相同對象,並使用 Object 類中的 equals() 方法來比較它們,您將得到“false”結果。 這是因為即使這些對象是相同的,它們也包含不同的引用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.