旋涡JAVA笔记--集合的前世今生2 —— 陌上人如玉

来源:互联网 发布:照片扫描软件手机版 编辑:程序博客网 时间:2024/06/02 18:00

承接上次的博客 这次要分享的是我在《疯狂JAVA笔记》中对于HashSet类的知识获取

HashSet是set接口的典型实现,大多时候是用的set集合就是HashSet,HashSet按照Hash算法来存储集合中的元素,具有很好的查询和存取性能。

HashSet具有以下特点

  1. 不能保证元素的排列顺序,顺序与添加顺序可能不同,并且会很混乱
  2. HashSet不是同步的,多线程访问HashSet要保证其同步性
  3. 几何元素可以为null

HashSet集合判断两个元素相等的标准是两个对象的equals()方法比较性等,而且两个对象的hashCode()方法返回值也相等。

hashSet判断集合元素相等的标准代码块:

//重写A类中equals的方法使其总是返回trueclass A{    @Override    public boolean equals(Object obj) {        return true;    }}//重写B类中的hashcode方法使其总是返回1class B{    @Override    public int hashCode() {        return 1;    }}//重写C类中的equals和hashCode方法使其分别返回true和2class C{    @Override    public boolean equals(Object obj) {        return true;    }    @Override    public int hashCode() {        return 2;    }}public class HashSet {    public static void main(String[] args) {        java.util.HashSet books = new java.util.HashSet();        books.add(new A());        books.add(new A());        books.add(new B());        books.add(new B());        books.add(new C());        books.add(new C());        System.out.println(books);    }}

**运行结果为:
[com.HashSet.B@1,
com.HashSet.B@1,
com.HashSet.C@2,
com.HashSet.A@74a14482,
com.HashSet.A@4554617c]**

注:两个A对象的equals()方法比较相等,但是这两个的hashCode值不同,HashSet将其当成两个对象存储在hash表的不同位置,两个B对象的hashCode值虽然相等但是,但由于未重写equals方法,故两个B对象是被HashSet当成两个对象存储在hash标的不同位置,但这时对于Hash表来说是比较麻烦的,Hash表会在同一个用链式结构保存多个对象,如果hashSet中两个以上的元素拥有相同的hashCode,将会导致性能下降。C对象虽然在books集合中添加了两个对象,但由于其equals比较和hashCode比较都相同,故hashSet认为是一个相同的元素,个只能添加一个成功,所以控制台输出的结果只有5个。

hash算法可以根基元素的hashCode值直接计算出元素的存储位置,从而快速定位出该元素。表面看气来HashSet集合中的元素没有索引,实际上由hashCode计算出来的存储位置值可以认定为一个索引,HashSet对比数组来说:数组的长度是固定的,索引是连续的,且不能随意增加数组的长度,但HashSet在这些方面做出的很出色

重写hashCode()方法的基本规则:

  1. 程序运行过程中,同一个对象多次调用hashCode()方法应该返回相同的值
  2. 当两个对象的equals方法比较返回True时,这两个对象的hashCode返回的值应该相等
  3. 对象中用作equals方法比较标准的实例变量,都应该用于计算hashCode值

重写hashCode方法的一般步骤:

  1. 把对象内每个有意义的实例变量(即每个参与equals方法比较标准的实例变量)计算出一个int类型的hashCode值计算方式如下:这里写图片描述
  2. 用第一步计算出的hashCode值组合计算出一个hashCode值返回
    eg: return f1.hashCode() + (int)f2
    注:为了避免直接相加产生偶然相等可以通过为各个实例变量的hashCode值乘以一个质数后在相加。

最后请大家注意:当向HashSet中添加可变对象时,必须十分小心。如果修改HashSet中的元素的话与集合中的其他对象相等,从而导致HashSet无法准确访问该对象。

谢谢大家捧场。

1 0
原创粉丝点击