HashSet集合的知识点

前一篇讲了整个Collection的概念跟常用的方法,这篇具体讲解一下关于HashSet的用法
HashSet是Set接口的实现,使用Set实现类时通常使用的就是该HashSet实现类,该类是按hash算法来存储集合中的元素,有良好的存储于查找性能

该类的特点

  • 无序不重复,集合内元素顺序与添加时元素顺序不一致
  • 集合中的元素可以为null
  • 该集合不是同步的,多个线程同时访问同一个HashSet,必须通过代码同步来保证集合内元素的同步

当调用集合的存储方法时,集合会调用被存储对象的hashCode方法获取该对象的hashCode值,根据该值决定对象在集合内的位置.如果两个元素的equals()方法返回为true ,而两个元素的hashCode()值不相等,此时两个元素将被当成不同的对象被存储在集合
所以该集合判断两个对象是否相等时,两个对象的equals()方法相等同时,两个元素的hashCode值也必须相等

public class SetTest {
    public static void main(String[] args) {
        HashSet set = new HashSet<>();
        //添加两个A对象
        set.add(new A());
        set.add(new A());
        System.out.println(set);
    }
}

//类A重写equals方法时总是返回true
class A{
    @Override
    public boolean equals(Object obj) {
        return true;
    }
}
 
  

如果两个元素的equals方法总返回true ,而hashCode返回不同的数值,此时集合还是会将两个元素放入集合中,从而违背了Set集合的不重复原则,所以在重写被添加元素的equals方法时,必须重写hashCode方法
两者的equals返回为true ,而hashCode返回为2,此时会违背Set集合不重复的原则

public class SetTest {
    public static void main(String[] args) {
        HashSet set = new HashSet<>();
        //添加两个A对象
        set.add(new B());
        set.add(new B());
        System.out.println(set);
    }
}
//类B重写hashCode方法,总返回1  
class  B{
    @Override
    public int hashCode() {
        return 1;
    }
}
 
  

如果两个元素的hashCode值相等,而equals方法返回false时,依然可添加成功,可是此时集合内会有两个相等hashCode值得元素,此时集合会使用链表形式保存两个元素,而集合读取时根据元素的hashCode获取元素,所以此时会造成性能上的下降
在这里插入图片描述

你可能感兴趣的:(集合,Java)