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

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

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

HashSet具有以下特点

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

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

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

//重写A类中equals的方法使其总是返回true
class A{
    @Override
    public boolean equals(Object obj) {
        return true;
    }
}
//重写B类中的hashcode方法使其总是返回1
class B{
    @Override
    public int hashCode() {
        return 1;
    }
}
//重写C类中的equals和hashCode方法使其分别返回true和2
class 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值