发在认证区了,这边人气好点...各位帮帮忙啊
http://community.csdn.net/Expert/topic/5553/5553367.xml?temp=.2240412
orz

解决方案 »

  1.   

    原题是这样的
    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?
      

  2.   

    public int hashCode() { return i; } 
    k2.i后来的值改变了,因此hashCode 也变了,所以remove不会将k2移除掉
    add和remove的时候都是根据计算hashCode来的
      

  3.   

    看来还是不知道hashCode()是用来干吗的。
      

  4.   

    看来还是不知道hashCode()是用来干吗的。
    =======================================
    关注。。
      

  5.   

    我在16,17行之间加如下的语句:
    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里面可以有相同的元素了么?
      

  6.   

    听下z_lping(Schemer)的意见...
      

  7.   

    16行执行以后,hashset里的k2.i和原来的k2.i都变成1(我用eclipse的debug看到的),这样的话hashcode()不是都相等了,18和20行的remove()是怎么判断的?
      

  8.   

    那不就是意味着HashSet里面可以有相同的元素了么?
    =============================================
    对了。但是这两个实例放在不同的篮子里。为什么不同的篮子呢?因为它们被放进去的时候,hashCode()是不一样的。
      

  9.   

    16行执行以后,hashset里的k2.i和原来的k2.i都变成1(我用eclipse的debug看到的),这样的话hashcode()不是都相等了,18和20行的remove()是怎么判断的?
    ======================================================
    那是因为这个k2是放在hashCode()是2的篮子里,当运行20行的时候,我们去hashCode()为1的篮子里找,自然找不到它,也就不能删除了呀。
      

  10.   

    这就了解了?那么,hashCode()到底是用来干么的呀?
      

  11.   

    那么,hashCode()到底是用来干么的呀?
    ====================
    下面有请z_lping(Schemer)为大家详细概括..
    大家鼓掌...噼里啪啦..
      

  12.   

    篮子啊,add()的时候放到对应的篮子里,然后remove()的时候再用hashcode()找对应的篮子,我是这样理解的,对么?一开始我忘了篮子这个概念
      

  13.   

    还有问下 z_lping,我在debug里看hashset 里面table里的元素有个hash字段 是不是就是这个"篮子"
      

  14.   

    这个不知道,我没有用Eclipse跑过Debug。理解了就好了。:-)
      

  15.   

    HashSet里面是用HashMap支持的(组合了一个HashMap实例来实现HashSet)调用HashSet的remove()方法其实就是调用HashMap的remove方法。HashSet里面的元素就是HashMap里面的Key。而HashMap里面的remove(Key key)方法会根据key的hashcode和equals()来移除元素。
    k2的i变了之后,HashMap计算它的hashCode的时候会计算出跟k1一样的结果,而实际上k2根本不和k1在一个桶里。它在哪个桶是由你put进去的时候决定的。所以hashmap去k1的桶里当然找不到k2,所以删不掉。
    鉴定完毕。
      

  16.   

    对于写入,通过对象的hashCode 计算出这个对象应存储在map的 index 的位置,这和数组一样,把一个对象放在其中的第index位置,但如果是查询,经过同样的算法,map可以直接通过key得到index,从第index取得这个值对象,实际上你修改完k2 之后map 会根据k2 现在的hashCode=2 来计算 index的值,得出来的index 和 k1 的index 相同!! 这样虽然在remove(k2) 实际上还是在remove(k1)!这也是为什么对于数据量稍大时,Hashtable的查询比数组具有更高的性能的原因(前提是hashcode设计得好),因为数组是要循环遍历才能找到,而hashtable 可以通过 index 一步搞定
      

  17.   

    感觉可以这样理解:
    添加时: 根据hashCode() 计算决定可以放进编号为 index 的桶,由equals()来决定是否放进去(桶里没有)
    删除时: 根据hashCode() 计算决定去哪个桶里删除,由equals()来决定具体删除哪个(删除equals返回true的,不过JDK源码里面在进行equals比较之前先比较了==,如果==返回true就不比较equals了,即使eqlas返回的是false)
      

  18.   

    HashSet - Hash table implementation of the Set interface. The best all-around implementation of the Set interface.