→阿童沐

財富==支撐一個人生存多長時間的能力!

导航

HashSet与hashCode相关性,以及HashSet注意事项-

Java内部实现HashSet的方式是通过HashMap实现的,HashMap内部有一个内部类,叫做Entry,所有的Key和Value在HashMap内部是封装为该类型的对象后,加入到当前HashMap内部的数组中的.

通过计算Key对象的hashCode来获得所对应的Entry对象在数组中存放的位置.如果hashCode相同,也就是数组中的当前位置已经有元素占用时,将会通过Entry对象内部的指针进行链接.

也就是说,HashMap内部是通过数组 + 链表的形式进行组织的.

下面是网上转载内容:

HashSet就是采用哈希算法存取对象的集合,它内部采用对某个数字n进行取余的方式对哈希码进行分组和划分对象的存储区域。Object类中定义了一个hashCode()方法来返回每个Java对象的哈希码,当从HashSet集合中查找某个对象时,Java系统首先调用对象的hashCode()方法获得该对象的哈希码,然后根据哈希码找到相应的存储区域,最后取出该存储区域内的每个元素与该对象进行equals方法比较,这样不用遍历集合中的素有元素就可以的到结论。可见,HashSet集合具有很好的对象检索性能,但是,HashSet集合存储对象的效率相对要低些,因为向HashSet集合中添加一个对象时,要先计算出对象的哈希码和根据这个哈希码确定对象在集合中的存放位置。

只有类的实例对象要被采用哈希算法进行存储和检索时,这个类才需要按要求覆盖hashCode方法。即使程序可能暂时不会用到当前类的hashCode方法,但是为它提供了一个hashCode方法也不会有什么不好,没准以后什么时候又用到这个方法了,所以,通常要求hashCode方法和equals方法一并被同时覆盖。

通常来说,一个类的两个实例对象用equals()方法比较的结果相等时,它们的哈希码也必须相等,但反之则不成立,即equals方法比较结果不相等的对象可以有相等的哈希码,或者说哈希码相同的两个对象的equals方法比较的结果可以不相等。

当一个对象被存储进HashSet集合中以后,就不能修改这个对象的那些参与计算哈希值的字段了,否则,对象修改后的哈希值与最初存储进HashSet集合中的哈希值就不同了,在这种情况下,即使在contains方法使用该对象的当前引用作为的参数去HashSet集合中检索对象,也将返回找不到对象的结果,这也导致无法从HashSet集合中单独删除当前对象,从而造成内存泄漏。

如下代码:

package cn.edu.bupt.testset;

import java.awt.Point;
import java.util.Collection;
import java.util.HashSet;

public class HashSetTest
{
    public static void main(String[] args)
    {
        Collection<Point> c = new HashSet<Point>();
        
        Point p1 = new Point(1, 2);
        Point p2 = new Point(2, 3);
        
        c.add(p1);
        c.add(p2);
        
        System.out.println(c.size());
        
        p2.setLocation(2,2);
        
        boolean tag = c.remove(p2);
        System.out.println(tag);
        System.out.println(c.size());
    }
}

运行结果如下:

转自:http://www.cnblogs.com/luochengor/archive/2011/12/05/2276828.html

posted on 2012-04-20 10:33  阿童沐  阅读(191)  评论(0)    收藏  举报