Set系列集合
Set集合特点:无序(添加数据的顺序和获取出的数据顺序不一致),不重复,无索引。
HashSet:无序、不重复、无索引
底层原理:基于哈希表存储数据的。
jdk8之前:哈希表底层是由数组和链表组成的
创建一个默认长度16的数组,默认加载因子为0.75,
数组名table,根据元素的哈希值对数组的长度做运算计算出应存入的位置,判断当前位置是否为null,如果是null直接存入,如果不为null,表示有元素,则调用equals方法比较相等,则不存;不相等,则存入数组
JDK8之前,新元素存入数组,占老元素位置,老元素挂下面
JDK 8开始之后,新元素直接挂在老元素下面
当数组中数量达到数组长度*负载因子(0.75),会将容量扩大为原来的 2 倍,并重新计算每个元素的存储位置。
JDK8开始:哈希表底层是由数组、链表和红黑树组成的。
JDK8开始,当链表长度超过8,且数组长度>=64时,自动将链表转成红黑树。
JDK8开始后,哈希表中引入了红黑树后,进一步提高了操作数据的性能。
HashSet集合元素的去重操作:
使用HashSet集合添加对象时,添加时,判断是否相同的条件时hashCode()是否相同,如果希望Set集合认为两个内容两个相同的对象是重复的,需要重写hashCode()和equals这两个方法。
LinkedHashSet:有序、不重复、无索引
依然是基于哈希表(数组,链表,红黑树)实现的。但是,它的每个元素都额外的多了一个双链表的机制记录它前后元素的位置(达到有序的目的)。
TreeSet:排序、不重复、无索引
底层是基于红黑树实现的排序,增删改查性能较好
Treeset集合存储自定义类型的对象时,必须定排序规则,支持如下两种方式来指定比较规则。
方式一
让自定义的类(如学生类)实现comparable接口,重写里面的compareTo方法来指定比较规则。
public class Student implements Comparable<Student>{private String name;private int age;private int score;
//默认getset方法已经包含
public String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", score=" + score +'}'+"\n";}
public int compareTo(Student o) {return this.age-o.age;}
方式二
通过调用Treeset集合有参数构造器,可以设置Comparator对象(比较器对象,用于指定比较规则,
public TreeSet(compapator<?super E>conparator)
当实现Comparator和comparable两个比较器同时实现时,优先使用Comparator比较器
在 TreeSet
中,如果同时提供了 Comparator
和 Comparable
两个比较器,并且 Comparator
比较的结果是相等的(即 compare
方法返回 0),那么 TreeSet
不会再调用 Comparable
的 compareTo
方法来进行进一步的比较。相反,TreeSet
会认为这些元素是相等的,并拒绝插入重复的元素。