原题是这样的 1. import java.util.*; 2. class KeyMaster { 3. public int i; 4. public KeyMaster(int i) { this.i = i; } 5. public boolean equals(Object o) { return i == ((KeyMaster)o).i; } 6. public int hashCode() { return i; } 7. } 8. public class MapIt { 9. public static void main(String[] args) { 10. Set<KeyMaster> set = new HashSet<KeyMaster>(); 11. KeyMaster k1 = new KeyMaster(1); 12. KeyMaster k2 = new KeyMaster(2); 13. set.add(k1); set.add(k1); 14. set.add(k2); set.add(k2); 15. System.out.print(set.size() + “:”); 16. k2.i = 1; 17. System.out.print(set.size() + “:”); 18. set.remove(k1); 19. System.out.print(set.size() + “:”); 20. set.remove(k2); 21. System.out.print(set.size()); 22. } 23. } What is the result? A. 4:4:2:2 B. 4:4:3:2 C. 2:2:1:0 D. 2:2:0:0 E. 2:1:0:0 F. 2:2:1:1 G. 4:3:2:1 answer:F 为什么20行不能删除k2?
public int hashCode() { return i; } k2.i后来的值改变了,因此hashCode 也变了,所以remove不会将k2移除掉 add和remove的时候都是根据计算hashCode来的
1. import java.util.*;
2. class KeyMaster {
3. public int i;
4. public KeyMaster(int i) { this.i = i; }
5. public boolean equals(Object o) { return i == ((KeyMaster)o).i; }
6. public int hashCode() { return i; }
7. }
8. public class MapIt {
9. public static void main(String[] args) {
10. Set<KeyMaster> set = new HashSet<KeyMaster>();
11. KeyMaster k1 = new KeyMaster(1);
12. KeyMaster k2 = new KeyMaster(2);
13. set.add(k1); set.add(k1);
14. set.add(k2); set.add(k2);
15. System.out.print(set.size() + “:”);
16. k2.i = 1;
17. System.out.print(set.size() + “:”);
18. set.remove(k1);
19. System.out.print(set.size() + “:”);
20. set.remove(k2);
21. System.out.print(set.size());
22. }
23. }
What is the result?
A. 4:4:2:2
B. 4:4:3:2
C. 2:2:1:0
D. 2:2:0:0
E. 2:1:0:0
F. 2:2:1:1
G. 4:3:2:1
answer:F
为什么20行不能删除k2?
k2.i后来的值改变了,因此hashCode 也变了,所以remove不会将k2移除掉
add和remove的时候都是根据计算hashCode来的
=======================================
关注。。
System.out.println("k1 hashCode: "+ k1.hashCode());
System.out.println("k2 hashCode: "+ k2.hashCode());
System.out.println("equals or not: "+ k1.equals(k2));从输出的结果来看,k1和k2的hashCode是相等的,k1.equals(k2))也返回,但是17行的set.size()仍然是2!
那不就是意味着HashSet里面可以有相同的元素了么?
=============================================
对了。但是这两个实例放在不同的篮子里。为什么不同的篮子呢?因为它们被放进去的时候,hashCode()是不一样的。
======================================================
那是因为这个k2是放在hashCode()是2的篮子里,当运行20行的时候,我们去hashCode()为1的篮子里找,自然找不到它,也就不能删除了呀。
====================
下面有请z_lping(Schemer)为大家详细概括..
大家鼓掌...噼里啪啦..
k2的i变了之后,HashMap计算它的hashCode的时候会计算出跟k1一样的结果,而实际上k2根本不和k1在一个桶里。它在哪个桶是由你put进去的时候决定的。所以hashmap去k1的桶里当然找不到k2,所以删不掉。
鉴定完毕。
添加时: 根据hashCode() 计算决定可以放进编号为 index 的桶,由equals()来决定是否放进去(桶里没有)
删除时: 根据hashCode() 计算决定去哪个桶里删除,由equals()来决定具体删除哪个(删除equals返回true的,不过JDK源码里面在进行equals比较之前先比较了==,如果==返回true就不比较equals了,即使eqlas返回的是false)