hashset是通过hashmap来实现的,将元素添加到hashset中就相当于添加到hashmap的键中,而hashmap添加元素的时候本身就会调用hash和equals方法来计算键值得hash值和判断是否重复,为什么添加到hashset中的元素还要添加hashcode和equals方法
解决方案 »
- soap消息中 mustUnderstand="0" or "1" 在xml规范中是如何解释的?
- ======求救:java 下载文件,提示:不可预料的压缩文件末端!======
- getJdbcTemplate().queryForList()的问题
- Apache+tomcat迁移到apache+Weblogic整合之动静分离问题?困惑两天了~
- struts2中的验证框架问题
- 我的课题是java applet实现记事本功能
- 还是jTable,怎么样才能出现水平滚动条
- 高手指点:factory究竟有什么用?
- 怎么运行java
- 在新增时,用mycat获取最新id时报错
- 多线程问题
- 新手求助,shiro集合SSM框架异常
hashset集合在将一个元素添加到集合中时(假设为一个自定义类,并重写了hashcode与equals方法),首先查看该元素所在的地址(hashcode计算出的值)中是否已有元素,如果没有,会直接将该元素添加到集合中,如果有元素,则进行equals方法比较,返回true,不添加,返回false,添加到集合
如果自定义类不重写hashcode与equals方法,将调用object类的hashcode与equals方法,Object类的hashcode使用的是随机值
那么hashset集合添加相同的元素依旧会成功,不能保证他的唯一性
还有一个 Treeset保证唯一性的是他的compareto方法的返回值 ,返回0 不添加,其他数则添加
往HashSet添加元素的时候,HashSet会先调用元素的hashCode方法得到元素的哈希值,然后通过元素的哈希值经过移位等运算,就可以算出该元素在哈希表中的存储位置。
情况1:如果算出元素存储的位置目前没有任何元素存储,那么该元素可以直接存储到该位置上。
情况2:如果算出该元素的存储位置目前已经存在有其他的元素了,那么会调用该元素的equals方法与该位置的元素再比较一次,如果equals返回的是true,那么该元素与这个位置上的元素就视为重复元素,不允许添加,如果equals方法返回的是false,那么该元素允许添加。所以一个对象要被存储入HashSet,必须重写该对象的hashCode方法和equals方法,且必须保证一致性。
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}