文章目录
- 三个特点
- 哈希值
- 三个实现类
- 1、HashSet
- 1.1 实例演示
- 方案一、去重机制
- 1)重写hashCode
- 2)重写equals
- 方案二、添加注解
- 2、LinkedHashSet
- 3、TreeSet
在Java中Set集合是一种重要的数据结构,可使用其去重特性,完成特定场景下的业务需要,记录下来,方便备查。
三个特点
无序、不重复、无索引
哈希值
int类型的随机值,每个Java对象都有一个哈希值,可调用Object的hashCode方法,返回对象自己的哈希值
特点
1、同一个对象多次调用hashCode方法返回的哈希值是相同的
2、不同对象,对应的哈希值一般是不相等,可能存在哈希碰撞,导致相等。
三个实现类
1、HashSet
特点:无序、不重复、无索引。
底层是 哈希表存储。
其详细流程如下:
第一步、创建一个默认长度为16,默认加权因子为0.75的数组,数据名为table;
第二步、根据元素的哈希值与数据长度计算出应存入的位置;
第三步、判断当前位置是否为null,若是null就直接存入,若位置不是null,表示有元素,则调用equals方法比较属性值,若是一样,则无需进行存放,如不一样,则要存入数组;
第四步、当数组存满到16*0.75=12时,即自动扩容,每次扩容成原来的两倍。
在JDK8之前,哈希表=数组+链表
数据因子 0.75
在JDK8以后,哈希表=数组+链表+红黑树,即当链表长度超过8,且数组长度大于等于64时,自动将链表转成红黑树。
1.1 实例演示
定义学生类Student
public class Student {private String name;private int age;private String phone;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getPhone() {return phone;}public void setPhone(String phone) {this.phone = phone;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", phone='" + phone + '\'' +'}' +"\n";}
}
分别定义3个student对象,放到HashSet对象中,运行代码查看效果。
public static void main(String[] args){Student s1 = new Student();s1.setName("Tom");s1.setAge(10);s1.setPhone("1111111");Student s2 = new Student();s2.setName("Tom");s2.setAge(10);s2.setPhone("1111111");Student s3 = new Student();s3.setName("Jerry");s3.setAge(11);s3.setPhone("222222");Set<Student> set = new HashSet<>();set.add(s1);set.add(s2);set.add(s3);System.out.println("结果输出为:"+set);
}
运行结果如下图所示。
运行结果发现 相同的对象并没有去重,可采用两种方案处理
方案一、去重机制
重写对象的hashCode和equals方法。
即在 student类中重写两个方法
1)重写hashCode
@Override
public int hashCode() {return Objects.hash(name, age, phone);
}
2)重写equals
@Override
public boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;return age == student.age && Objects.equals(name, student.name) && Objects.equals(phone, student.phone);
}
右键 -> Generate -> equals() and hashCode(),即可生成两个方法。
执行结果如下图所示。
方案二、添加注解
在 student 类上加上 Data 注解
import lombok.Data;
@Data
public class Student {private String name;private int age;private String phone;
}
执行结果如下所示。
2、LinkedHashSet
有序,不重复,无索引
3、TreeSet
排序,不重复,无索引,默认按大小升序排序