[英]Overriding `equals()` method gives unexpected result in `HashMap`
It is question from OCJP 6 exam, so it is intentionally not fully correct (but legal). 这是来自OCJP 6考试的问题,因此故意不完全正确(但合法)。
Given code: 给定代码:
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());
}
}
Why output is 2? 为什么输出是2? I mean,
equals
method is not overriden corretcly, so t1.day == t2.day
supposed to be false! 我的意思是,
equals
方法没有相应地重写,所以t1.day == t2.day
应该是假的! Am I'm missed something? 我错过了什么吗?
It's because: 这是因为:
"Mond" + "a" + "y"
is evaluated at compile time to "Monday" thus resulting in just one instance in string pool. 在编译时被评估为“星期一”,从而导致字符串池中只有一个实例。 There is a much simpler test to examine this behavior:
有一个更简单的测试来检查这种行为:
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
Examples above should give you some overview on how the compiler treats string concatenation. 上面的示例应该为您提供有关编译器如何处理字符串连接的概述。
And to be on the safe side, always use: 为了安全起见,请始终使用:
return ((ToDos) o).day.equals(day);
Just adding to previous answers ... another example illustrating the point: 只是添加到以前的答案...说明这一点的另一个例子:
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
Both a
and c
point to the same object in the String pool. a
和c
指向String池中的同一个对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.