分享

自定义类型作为HashMap的Key

 大飞哥书屋 2017-02-16
如果把自定义的对象作为HashMap的key,怎么确保它的唯一性?

HashMap存数据的基本流程:
1、当调用put(key,value)时,首先获取key的hashcode,int hash = key.hashCode();
2、再把hash通过一下运算得到一个int h
3、得到h之后,把h与HashMap的承载量进行逻辑与运算,即 h &(length-1)
这样得到的结果就是一个比length小的正数,我们把这个值叫做index。
其实这个index就是索引将要插入的值在数组中的 位置。第2步那个算法的意义就是希望能够得出均匀的index
4、我们用table[index]表示元素需要存储的位置。
先判断该位置上有没有元素,
没有:创建一个Entity<K,V>对象,在table[index]位置上插入,这样插入结束;
有  :通过链表的遍历方式去逐个遍历,看看有没有已经存在的key
有:新的value替换老的value;
没有:在table[index]插入该Entity,把原来在table[index]位置上的Entity赋值给新的 Entity的next,这样插入结束。 

使用HashMap,如果key是自定义的类,就必须重写hashcode()和equals()。

     1.hashcode()和equals()是在哪里被用到的?什么用的?

     HashMap是基于散列函数,以数组和链表的方式实现的。
 而对于每一个对象,通过其hashCode()方法可为其生成一个整形值(散列码),该整型值被处理后,将会作为数组下标,存放该对象所对应的Entry(存放该对象及其对应值)。
 equals()方法则是在HashMap中插入值或查询时会使用到。当HashMap中插入 值或查询值对应的散列码与数组中的散列码相等时,则会通过equals方法比较key值是否相等,所以想以自建对象作为HashMap的key,必须重写 该对象继承object的hashCode和equals方法。
    
     2.本来不就有hashcode()和equals()了么?干嘛要重写,直接用原来的不行么?
     
      HashMap中,如果要比较key是否相等,要同时使用这两个函数!因为自定义的类的hashcode()方法继承于Object类,其hashcode码为默认的内存地 址,这样即便有相同含义的两个对象,比较也是不相等的,例如,生成了两个“羊”对象,正常理解这两个对象应该是相等的,但如果你不重写 hashcode()方法的话,比较是不相等的!
      HashMap中的比较key是这样的,先求出key的hashcode(),比较其值是否相等,若相等再比较equals(),若相等则认为他们是相等 的。若equals()不相等则认为他们不相等。如果只重写hashcode()不重写equals()方法,当比较equals()时只是看他们是否为 同一对象(即进行内存地址的比较),所以必定要两个方法一起重写。HashMap用来判断key是否相等的方法,其实是调用了HashSet判断加入元素 是否相等.
 
 
例如:注意:重写hashCode()时应该尽量使用不会改变的属性  
public class MapObjectForm {  
    private String sydmc;  
    private String scmc;  
  
    public MapObjectForm(String sydmc, String scmc) {  
        this.sydmc = sydmc;  
        this.scmc = scmc;  
    }  
  
    @Override  
    public boolean equals(Object obj) {  
        MapObjectForm tf = (MapObjectForm) obj;  
        return this.scmc.equals(tf.scmc) && this.sydmc.equals(tf.sydmc);  
    }  
  
    @Override  
    public int hashCode() {  
        int result = 17;  
        result = result * 31 + scmc.hashCode();  
        result = result * 31 + sydmc.hashCode();  
        return result;  
    }  
  
}  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多