类HashSet
简介
java.util.HashSet 是 Set 接口的一个实现类,它所存储的元素是不可重复的,并且元素都是无序的(即存取顺序不一致)。 java.util.HashSet 底层的实现其实是一个 java.util.HashMap 支持。HashSet 是根据对象的哈希值来确定元素在集合中的存储位置,因此具有良好的存取和查找性能。保证元素唯一性 的方式依赖于: hashCode 与 equals 方法。特点:
- 不允许存储重复的元素
- 没有索引,不能使用普通的for循环遍历。(可以使用增强for和迭代器遍历)
- 一个无序的集合,存储元素和取出元素的顺序不一致
- 底层是一个哈希表结构(查询的速度非常快)
哈希值
哈希值:是一个十进制的整数,由系统随机给出(就是对象的地址值,是一个逻辑地址,是模拟出来得到的地址,不是实际的物理地址)。在Object 类有一个方法,可以获取对象的哈希值。int hashCode()返回对象的哈希码值。HashSet集合存储数据的结构(哈希表)
什么是哈希表呢? 在JDK1.8之前,哈希表底层采用数组+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里。但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。而JDK1.8中,哈希表存储采用数组+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间。set集合存储元素不重复的原理
当我们使用set中的add方法添加元素的时候,add方法会调用要添加的元素的hashCode方法,计算元素的哈希值。之在集合中寻找有没有重复的哈希值,没有则添加元素进入set集合。如果有,则要添加元素会调用equals方法,比较2个哈希值相同的元素,如果equals方法的返回值为true,则判断两个元素相同,要添加的元素不会存储到集合中。如果equals方法返回值为false,则会添加到元素中。
总结: JDK1.8引入红黑树大程度优化了HashMap的性能,那么对于我们来讲保证HashSet集合元素的唯一,其实就是根据对象的hashCode和equals方法来决定的。 如果我们往集合中存放自定义的对象,那么保证其唯一,就必须复写hashCode和equals方法建立属于当前对象的比较方式。 代码举例:package demo03; import java.util.Objects; public class Person { // 成员变量 private String name; //无构造 public Person() { } //全参数构造 public Person(String name) { this.name = name; } //重写toString @Override public String toString() { return "Person{" + "name='" + name + '\'' + '}'; } //get /set方法 public String getName() { return name; } public void setName(String name) { this.name = name; } // 重写hashCode 和equals方法 @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return Objects.equals(name, person.name); } @Override public int hashCode() { return Objects.hash(name); } }
定义HashSet集合
SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。package demo03; import java.util.HashSet; import java.util.Set; public class HashSetTest { public static void main(String[] args) { // 多态,创建子类对象 Set<Person> set = new HashSet<>(); //添加自定义对象 set.add(new Person("张三")); set.add(new Person("李四")); set.add(new Person("张三")); set.add(new Person("王五")); //遍历集合 for (Person person : set) { // 获取每个对象的 System.out.println(person); } } }
执行结果

更多精彩