覆盖“equals()”方法会在“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 都指向字符串池中的同一对象。

最新更新