黑马程序员技术交流社区
标题:
关于HashSet一个问题
[打印本页]
作者:
IT人
时间:
2013-11-29 10:30
标题:
关于HashSet一个问题
在重写了equals没有重写hashCode方法的情况下:
Collection colletions = new HashSet();
ReflectPoint pt1 = new ReflectPoint(3,3);
ReflectPoint pt2 = new ReflectPoint(5,5);
ReflectPoint pt3 = new ReflectPoint(3,3,);
collections.add(pt1);
collections.add(pt2);
collections.add(pt3);
collections.add(pt1);
System.out.println(collections.size());
打印的结果为什么有可能是3,也有可能是2
作者:
刘敏
时间:
2013-11-29 10:49
怎么会有2出现了,我按你的说法把你的代码执行了1000遍,结果只有3.
import java.util.*;
class ReflectPoint
{
private int x;
private int y;
ReflectPoint(int x, int y)
{
this.x = x;
this.y = y;
}
public boolean equals(Object obj)
{
ReflectPoint tmpObj = (ReflectPoint)obj;
return((this.x == tmpObj.x) && (this.y == tmpObj.y));
}
}
class CollectionDemo
{
public static void main(String[] args)
{
myTestFunc();
}
static void myTestFunc()
{
for(int i=0; i<1000;i++)
{
Collection collections = new HashSet();
ReflectPoint pt1 = new ReflectPoint(3,3);
ReflectPoint pt2 = new ReflectPoint(5,5);
ReflectPoint pt3 = new ReflectPoint(3,3);
collections.add(pt1);
collections.add(pt2);
collections.add(pt3);
collections.add(pt1);
System.out.println(collections.size());
}
}
}
作者:
Jim-剣◆﹏
时间:
2013-11-29 10:56
本帖最后由 Jim-剣◆﹏ 于 2013-11-29 13:59 编辑
这要看你的重写的equals是怎么实现的
你首先得明确hashSet存储去除重复元素的机制:先比较元素的hashCode,如果hashCode相同,则再比较equals,如果hashCode和equals都相同,那么这个元素就不会被添加进集合,如果hashCode不同,则不需要比较equals,直接添加进集合
ReflectPoint pt1 = new ReflectPoint(3,3);
ReflectPoint pt2 = new ReflectPoint(5,5);
ReflectPoint pt3 = new ReflectPoint(3,3,);
pt1,pt2,pt3,没有重写hashCode(),那么他们的hashCode()就是继承父类Object的hashCode()
查看源代码可以知道,父类Object的hashCode()是关联内存地址值的,而pt1,pt2,pt3这三个对象都是通过关键字new出来的,内存地址必定不一样,所以,pt1,pt2,pt3的hashCode()值也必定不一样
collections.add(pt1);
collections.add(pt2);
collections.add(pt3);
这三个可以直接添加进集合
对于再写一句collections.add(pt1);
这个当楼主你重写equals是这
public boolean equals(Object obj){
rerurn false;
}
复制代码
样的时候
此时打印结果是4
当楼主你重写的equals方法关联到对象的属性值时,判断依据是对象的属性时,就不能添加进去
此时打印结果就是3
重点看你怎么实现equals方法
不过一般没人会写一个不做任何比较直接返回boolean值的equals方法,但是是存在这种可能的
--------------------------------------------------------------------------------------------------分割线
以上说法没经过实践仓促回复,后来经过验证,发现了就算在equals中直接返回一个false还是不能成功添加,打印结果还是为3
似乎java有别的机制去除重复元素,并不只是根据hashCode和equals来工作的
故另外开贴咨询大牛,详情请移步
http://bbs.itheima.com/forum.php?mod=viewthread&tid=101147&page=1&extra=#pid566897
作者:
李文帅
时间:
2013-11-29 11:52
对于HashSet集合,存放的元素是无序的,并且不允许存放重复元素
当实例化对象时,系统会为每个对象开辟一块空间,每个对象都会有一个hashCode值,而每一个对象的hashCode值是互不相同的
对于楼主的程序ReflectPoint类中
如果未复写hashCode()方法,主函数中实例化对象pt1,pt2,pt3都有各自的hashCode值,并且互不相同,所以执行添加元素操作时pt1,pt2,pt3都成功存入,对于第四个添加操作,由于pt1已存在,所以添加失败,楼主可以添加代码验证:System.out.println(collections.add(pt1));所以打印结果是3
如果复写了hashCode方法,主函数中实例化对象pt1和pt3指向同一个对象,所以集合中成功添加的元素只有两个,所以打印结果是2
下面是我写的代码:
import java.util.*;
public class Foo {
public static void main(String[] args) {
Collection collections = new HashSet();
ReflectPoint pt1 = new ReflectPoint(3,3);
ReflectPoint pt2 = new ReflectPoint(5,5);
ReflectPoint pt3 = new ReflectPoint(3,3);
System.out.println(collections.add(pt1));
System.out.println(collections.add(pt2));
System.out.println(collections.add(pt3));
//由于pt1在集合中已存在,所以打印结果是false,即添加失败
System.out.println(collections.add(pt1));
System.out.println(collections.size());
}
}
class ReflectPoint{
private int x;
private int y;
/*
public int hashCode(){
return x + y*39;
}
如果未复写hashCode(),则pt1和pt3的hashCode值是不同的,
则System.out.println(collections.add(pt3));打印结果是true,即添加成功
所以集合中只添加了三个元素
如果复写hashCode(),则pt1和pt3的hashCode值是相同的,
则System.out.println(collections.add(pt3));打印结果是false,即添加失败
所以集合中只添加了两个元素
*/
public ReflectPoint(int x,int y){
this.x = x;
this.y = y;
}
public int getX(){
return x;
}
public int getY(){
return y;
}
public boolean equals(Object obj){
if(!(obj instanceof ReflectPoint))
throw new ClassCastException("类型不匹配!");
ReflectPoint r = (ReflectPoint)obj;
return this.x==r.x && this.y==r.y;
}
}
复制代码
这是我个人的理解,希望能够帮得到你
作者:
IT人
时间:
2013-11-29 16:03
听教程!上面说可能出现2,可是我也执行了几遍!但是还是3,谢谢了!
作者:
简★零度
时间:
2013-11-30 20:38
问题解决了就把类型改成提问结束1
作者:
che201311
时间:
2013-11-30 21:02
hashcode有可能一样在同一个卡块中
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2