簡體   English   中英

添加 equals() 和 hashCode() 方法會破壞某些東西嗎

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM