JAVA技术(二)——HashSet&hashcode

一、Introspection 

作为J2SE5.0提出的新特性,在介绍Introspection (内省)之前,需要先介绍JavaBean,我们常说的JavaBean跟java内省中所特指的JavaBean还是有些不同的。在内省中指的JavaBean是一种特殊的java类,主要用于传递数据信息,使用get、set方法来确定类属性。去掉set、get前缀,剩余的部分就是属性名

JDK中提供了对JavaBean进行操作的API,这套API就称为内省。

如果需要自己通过getX()来访问类私有属性,存在一定难度。内省的作用就在于把JavaBean用作普通类来操作。类A中有属性name,那我们可以通过getName,setName来得到其值或者设置新的值。通过getName/setName来访问name属性,这就是内省的默认规则

原理是通过类Introspector来获取某个对象的BeanInfo信息,然后通过BeanInfo来获取属性的描述器(PropertyDescriptor),通过这个属性描述器就可以获取某个属性对应的getter/setter方法,然后我们就可以通过反射机制来调用这些方法

之所以介绍内省,主要是经常结合着反射进行使用,通过反射获取对象的属性,接着使用内省对属性进行赋值。这是对内省的主要应用场景。

 

二、ArrayList 和HashSet

ArrayList是一组有序的集合,当对象被添加到ArrayList时,对象会先找到第一个空缺的区域,装入对象的引用,接下来,第二个对象依次在第二个位置增加,如果发现有相同的对象,也是按照顺序放进去。也就是说,在ArrayList里,每有一个对象就会放入一个引用,且并不检查对象是否重复,有多少装多少。

HashSet当放入对象时,首先查看里面是否有这样一个对象,如果有,则不放,除非将已经存在的对象删除。

如果做这样一个测试,分别将point1、2、3,三个对象存入ArrayList 和HashSet集合中,打印集合size大小可得:

	public static void collectionTest()
	{
		Point point1=new Point(1,1);
		Point point2=new Point(1,1);
		Point point3=new Point(2,2);
		Collection c=new HashSet();//2
		//Collection c=new ArrayList();//3
		c.add(point1);
		c.add(point2);
		c.add(point3);
		
		point1.setY(6);
		c.remove(point1);
		System.out.println(c.size());		
	}
      ArrayList的size是3,而HashSet是2。因为使用Hashset时,point1、2指向同一个对象引用,所以存入point1之后,2就不会在被放入hashSet。


三、HashSet 和hashCode方法

     1、HashSet存储原理

如果想查找一个集合中是否含有某个对象,通常是逐一的取出每个元素与要查找的对象进行比较,当发现某个元素equals目标对象时,则停止继续查找并返回信息

但是如果一个集合中成百上千个元素,这种方法就略显笨拙于是,有人发明了一种哈希算法来提高效率,原理主要是:将集合分为若干个存储区域,同时每个对象可以计算出一个哈希码,可以将哈希码分组,每个组分别存储进对应的存储区域,根据一个对象的哈希码就可以确定该对象应该存储在某个区域。

这样把存储区域分而治之,同时将对象以hash码进行标记,存入不同区域,大大提高了查找效率。

2、HashCode方法

HashSet就是采用哈希算法存储对象的集合,他内部采用对某个数组n进行取余的方法对哈希码进行分组用于划分对象的存储区域,同时每个Object类中定义了一个HashCode方法返回每个Java对象的哈希码

当从HashSet集合中查找到某个对象时。Java系统首先调用对象的hashCode方法获得对象的哈希码,然后根据哈希码找到对应的存储区域,最后取出该存储区域的每个元素与该对象进行equals方法的比较,这样不用遍历集合中的所有元素就可以得到结论

可见,HashSet集合具有很好的对象检索性能,但是牺牲的就是添加对象时的效率,因为向HashSet集合中添加对象的时候,首先要计算出来对象的哈希码和根据这个哈希码来确定对象在集合中的存放位置。

3、内存溢出问题

当一个对象被存储到HashSet集合中以后,如果对该对象进行直接修改,导致修改以后的哈希码与最初存储对象的哈希码不相等这样使得查找该对象时,还从原来的存储区寻找,结果当然是找不到对象,这也会导致无法从Hash集合中单独的删除当前的对象,使得区域一直被占用,从而造成内存泄漏问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值