关闭

Java中Map和Set容器如何存对象的

标签: javahashmap
818人阅读 评论(0) 收藏 举报
分类:

 之前看到过这样一个问题,大概是:能否把一个对象(自定义,没有任何方法)的两个实例同时存放到同一个Set中去?

 当时很懵,但是这几天偶然看了Set和Map的源码就比较明了了。这里总结一下。

 首先,大体上为了存储,有通过树来存数据的,也有通过散列(hash)来存数据的,而且Set的实现其实就是维护了一个对应的Map(如HashSet就是构造一个HashMap),Set的值就是Map的键。所以这里只讨论TreeMap和HashMap。

TreeMap实现put和get

 TreeMap主要是通过红黑树实现的。这里要求Key是实现了Comparable接口的。所以在TreeMap内部,就是通过compare方法来判断是否放入的键相同。以及你通过get获取元素时,也是通过compare方法来查找的。所以同一个对象的多个实例是否能同时存入Map/Set,就要看你如何定义compare方法了。

HashMap实现put和get

 HashMap以及其优化类,都是通过计算散列值来查找的。大概方式是,所有的key会算出一个hashcode,根据这个hashcode得到在容器内部的槽位(这里注意hashcode不要求唯一,因为即使有多个key在同一个槽位,也可以通过一个线性查找来获得最后结果),然后如果有put或者get方法,不外乎就是通过equals方法来看这个槽位中的其他key和要进行操作的是否相等,如果相等说明已经存在,对于put,则无法插入,对于get,则会进一步返回这个key的value。

 所以你会发现,当一个HashMap(或者HashSet)中的Key是一个对象时,那么主要看这个对象对于hashcode和equals方法的重写了。一般的,如果没有重写,直接继承Objec类的方法,那么hashcode是取得地址,equals方法是比较地址值。所以自然对于最开始的问题,是可以把两个实例放到同一个set中去的,因为他们有不同的地址,当然当你重写了hashcode和equals方法就不一定了(事实上,如果你需要用到自定义的类做Key或者放到Set中去,你需要注意是否需要重写hashcode和equals方法)。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:28734次
    • 积分:504
    • 等级:
    • 排名:千里之外
    • 原创:21篇
    • 转载:0篇
    • 译文:0篇
    • 评论:11条
    最新评论