A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 李金中 于 2014-2-12 22:50 编辑

package com.itheima;
import java.util.HashSet;
import java.util.Iterator;
public class HashSetTest {
public static void main(String[] args)
{
  Demo d1 = new Demo(1);
  Demo d2 = new Demo(2);
  
  HashSet hs = new HashSet();
  hs.add(d1);
  hs.add(d2);
  d2.setI(3);
  System.out.println(hs.remove(d2));//hashCode返回值变了,所以找不到元素,删除失败。
  Iterator it = hs.iterator();
  while(it.hasNext())
  {
   System.out.println(it.next());//为什么能找到元素,打印成功
  }
}
}
class Demo
{
Demo(int inum)
{
  i = inum;
}
public void setI(int inum)
{
  i = inum;
}
public int hashCode()
{
  return i;
}
public boolean equals(Object obj)
{
  return true;
}
public String toString()
{
  return String.valueOf(i);
}
private int i;
}

看代码注释的两行,当重写hashCode时,不能随便修改跟hashCode有关的字段属性,因为你可能检索不到添加的对象了,可是为什么调用iterator还能打印出来该对象。。。

评分

参与人数 1技术分 +1 收起 理由
滔哥 + 1

查看全部评分

6 个回复

倒序浏览
d2.setI(3);这句话把d2的hashcode值从2变成3
hs.remove(d2);这句话是根据d2进行删除此时d2的hashcode已经是3了,在hs中没有3
Iterator it = hs.iterator();
while(it.hasNext())
{
   System.out.println(it.next());     //Iterator遍历的时候不调用hashCode()方法,和hashcode值无关吧
}

评分

参与人数 1技术分 +1 收起 理由
滔哥 + 1

查看全部评分

回复 使用道具 举报
程澄 发表于 2014-2-12 21:02
d2.setI(3);这句话把d2的hashcode值从2变成3
hs.remove(d2);这句话是根据d2进行删除此时d2的hashcode已经 ...

。。不是根据hashcode去寻找 集合元素么。。存储的时候,不是根据hashcode么,那么 遍历查找该元素的时候,难度跟hashcode无关?那你还能根据什么查找。。。
回复 使用道具 举报
集合只是持有对象的引用,集合删除元素时,因为哈希值变了,没有删除成功,但并不代表集合中没有那个元素了,只是代表HashSet集合中的那个元素的位置变化了,所以在遍历集合时仍然有那个对象存在,如果那个对象不见了,那才叫做奇怪了,就好比你原本坐在教室的4组,现在老师要找你出去,但是老师没有叫你名字,而是在4组所有学生里面找,但是这时候你跑1组玩去了,老师没找到,那么你就仍然在教室。

评分

参与人数 1技术分 +1 收起 理由
滔哥 + 1

查看全部评分

回复 使用道具 举报
panzhenglian 发表于 2014-2-12 22:41
集合只是持有对象的引用,集合删除元素时,因为哈希值变了,没有删除成功,但并不代表集合中没有那个元素了 ...

靠谱!!!
回复 使用道具 举报
李金中 发表于 2014-2-12 22:03
。。不是根据hashcode去寻找 集合元素么。。存储的时候,不是根据hashcode么,那么 遍历查找该元素的时候 ...

可是我实验,用Iterator遍历时,没有调用hashCode()方法啊
回复 使用道具 举报
程澄 发表于 2014-2-12 22:56
可是我实验,用Iterator遍历时,没有调用hashCode()方法啊

。。。不知道。。。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马