簡體   English   中英

覆蓋`equals()`方法會在`HashMap`中產生意外結果

[英]Overriding `equals()` method gives unexpected result in `HashMap`

這是來自OCJP 6考試的問題,因此故意不完全正確(但合法)。

給定代碼:

class ToDos {
    String day;

    public ToDos(String d) {
        day = d;
    }

    public boolean equals(Object o) {
        return ((ToDos) o).day == day;
    }

    public int hashCode() { return 9; }
}

public class MapEQ {

    public static void main(String[] args) {
        Map<ToDos, String> map = new HashMap<ToDos, String>();

        ToDos t1 = new ToDos("Monday");
        ToDos t2 = new ToDos("Mond" + "a" + "y");
        ToDos t3 = new ToDos("Tuesday");

        map.put(t1, "a");
        map.put(t2, "b");
        map.put(t3, "c");

        System.out.println(map.size());
    }

}

為什么輸出是2? 我的意思是, equals方法沒有相應地重寫,所以t1.day == t2.day應該是假的! 我錯過了什么嗎?

這是因為:

"Mond" + "a" + "y"

在編譯時被評估為“星期一”,從而導致字符串池中只有一個實例。 有一個更簡單的測試來檢查這種行為:

System.out.println("Mond" + "a" + "y" == "Monday");  //true

String y = "y";
System.out.println("Mond" + "a" + y == "Monday");  //false

final String y2 = "y";
System.out.println("Mond" + "a" + y2 == "Monday");  //true

上面的示例應該為您提供有關編譯器如何處理字符串連接的概述。

為了安全起見,請始終使用:

return ((ToDos) o).day.equals(day);

只是添加到以前的答案...說明這一點的另一個例子:

String a = "Monday";
String b = new String("Monday");
String c = "Monday";

(a == b)      // false
(a.equals(b)) // true

(a == c)      // true
(a.equals(c)) // true

ac指向String池中的同一個對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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