Question 174
Click the Exhibit button.
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
答案是F我觉得应该输出2110啊。谁能解释下为什么这么输出?

解决方案 »

  1.   

    因为重写了 equals(Object o) 和 hashCode() 方法
     在java 中 判断两个对象是否相等 是 判断两个对象的 哈希码是否相等
     
     在这个程序中 hashCode() 方法返回自己持有的 i
     
     那么比较相等也就变成了比较 两个 KeyMaster 所持有的 i 是否相等 Set <KeyMaster> set = new HashSet <KeyMaster>(); 
     KeyMaster k1 = new KeyMaster(1); 
     KeyMaster k2 = new KeyMaster(2); 
     set.add(k1); set.add(k1); 
     set.add(k2); set.add(k2); 
     //到这里 set 中有两个对象 k1 , k2 System.out.print(set.size() + “:”); 
     k2.i = 1; 
     //k2 所持有的 i 变成了 1 与 k1 所持有的 i=1 相等
     //System.out.print(k1.equals(k2));//result = true (你可以在这个地方加上这一句代码)
     System.out.print(set.size() + “:”); 
     set.remove(k1); 
     //根据上面的条件,加上重写的 hashCode() 方法 构成了 set 中有两个相等的 KeyMaster(你可以)
     //set 中本来是不充许出现重复值的 但当不幸有两个相同(只出现在与此程序类似的情况中)的对象时,只会删除其中一个
     System.out.print(set.size() + “:”); 
     set.remove(k2); 
     //不再有与 k2 相同的对象 不会删除
     System.out.print(set.size()); 
     你只要把 hashCode() 方法注释 就可以看到你想要的结果
      

  2.   

    12行和13行按照hashCode给两个对象k1,k2分配了内存空间。调用remove的时候,还要用hashCode来寻找对象。16行并
    没有改变k2的内存地址,但是20行所用的hashCode已经不是由“2”生成的了。所以,找不到k2的地址,因此删不掉。
    下面的程序可以删掉:
    import java.util.*;
    class KeyMaster{
    public int i;
    public KeyMaster(int i){this.i=i;}
    public boolean equals(Object o){return i==((KeyMaster)o).i;}
    public int hashCode(){return i;}
    }
    public class MapIt{
    public static void main(String[] args){
            Set<KeyMaster> set=new HashSet<KeyMaster>();
            
             KeyMaster k1=new KeyMaster(1);
             KeyMaster k2=new KeyMaster(2);
             set.add(k1);set.add(k1);
             set.add(k2);set.add(k2);
              System.out.println(set);
              k2.i=1;
             
             System.out.println(set);
            
             set.remove(k1);
             System.out.println(set);
          
             set.remove(k2);
             System.out.println(set);
             k2.i=2;//把k2的哈西码再找回来
             set.remove(k2);
             System.out.println(set.size());
          }
    }