关于Set集合的感想

     这几天一直在纠结一个问题,毕老师在视频中讲到,Set集合的特点是可以保证元素的唯一性(即保证元素的不重复),我觉得这个说法不大准确,为什么呢,其实是有办法让它出现“重复”的元素,为什么打引号?因为这涉及到你怎么理解的问题,请看下面的例子:

import java.util.*;
class A
{
	private int a;
	A(int a){this.a=a;}
	public int hashCode()  	//重写Object的hashCode方法
	{
		return this.a;		
	}
	public boolean equals(Object obj)//重写Object的equals方法
	{
		A r=(A)obj;
		if (r.a==this.a)
		{
			return true;
		}
		return false;
	}
	public void  Get(){System.out.println(this.a);}
	public void Set(int a){this.a=a;}
}
class  Blog
{
	public static void main(String[] args) 
	{
		HashSet hs=new HashSet(); //没有使用泛型,其实不大严格
		hs.add(new A(9));
		hs.add(new A(8));
		hs.add(new A(-6));
		hs.add(new A(3));
		hs.add(new A(5));		
		hs.add(new A(8)); 	//这个必然添加不进去,因为根据规则首先比较的是A对象的hashCode方法,而此处被改写为返回类A的对象中的a值
		
	/*	HashSet s=new HashSet();
		s.add(new Integer(1));
		s.add(new Integer(2));
		s.add(new Integer(3));
		s.add(new Integer(1));
	*/

		Show(hs);
		Iterator it=hs.iterator();
		A first=(A)it.next();  
		first.Set(8);			//修改第一个元素的值

		System.out.println("这是修改之后的值");
		Show(hs);	
	}
	static void Show(HashSet hs)
	{
		Iterator it=hs.iterator();
		while (it.hasNext())
		{
			A aa=(A)it.next();
			aa.Get();
		}
	}
}



上面的结果说明什么?为什么我刚刚说那个"重复"全看个人怎么理解? 

我个人认为当集合的元素是引用型时,若我们不去重写hashCode方法和equals方法时,new出来的两个对象的hashcode极有可能不同(为什么不是一定?因为群友说还是有可能相同,具体原因我也不是很清楚,不了解这个算法,希望大虾指导),如果不同,系统会认为两个是不同的对象直接存进集合,若是相同那么在比较equals方法的时候会比较两个引用型数据的地址,下面的Object源码可以证明:  

public boolean equals(Object obj) {  
    return (this == obj); 

综合起来可以这样说,当集合的元素是引用类型时,若我们没有重写hashCode方法和equals方法,元素必定不相同,但是当我们重写了这两个方法之后,这个"相同"就具有另外的含义了,这个含义是我们定义的,在上面的程序中,这个"相同"的含义是,只要两个元素的a值是一样的话,我们就认为相同,程序中重新改写了第一个元素的a属性,这样就这个定义的话,我们就实现了元素的相同。

    另外还有一个重要的问题要解决,依照上面对引用类型相同的定义,new 产生的两个引用型数据在不改写hashCode方法和equals方法时,两元素必然不同,那么这样的话,

  

HashSet s=new HashSet();  
s.add(new Integer(1));  
s.add(new Integer(2));  
s.add(new Integer(3));  
s.add(new Integer(1));  
     这种做法最后的结果是不是应该有两个1呢??当然,如果我们没改写的话,当然应该是两个呢,但事实上Integer类确实改写了,下面的源码可以证明这点:

public int hashCode() {  
    return value;  
}  
public Integer(int value) {  
        this.value = value;  
}  
hashcode比较的就是他的属性而不是经计算得到的hashcode值



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值