集合4、集合_Collection接口_Set接口

Set接口的使用

存储无序的不可重复的数据

三种实现类:

  • HashSet:作为Set接口的主要实现类;线程不安全;可以存储 null 值
  • LinkedHashSet:作为HashSet的子类;遍历其内部数据时,可以按照添加的顺序遍历;对于频繁的遍历操作,LinkedHashSet的效率比HashSet高
  • TreeSet:可以按照添加对象的指定属性,进行排序

:1. Set接口中没有额外定义新的方法,使用的都是Collection中声明过的方法

​ 2. 向Set中添加的数据,其所在类一定要重写hashCode()和equals()且重写的hashCode()和equals()尽可能保持一致:相等的对象具有相等的散列码

一、理解无序性与不可重复性

以HashSet为例说明

  1. 无序性:不等于随机性。存储的数据在底层数组中并非按照数组索引的顺序添加,而是根据数据的哈希值决定的
  2. 不可重复性:保证添加的元素按照equals()判断时,不能返回true:即相同的元素只能添加一个

二、Set中添加元素的过程(以HashSet为例)

我们向HashSet中添加元素 a,首先调用元素 a 所在类的hashCode()方法,计算元素 a 的哈希值,此哈希值接着通过某种算法计算出在HashSet底层数组中存放的位置(即:索引位置),判断数组此位置上是否有元素:

  1. 如果此位置上没有其他元素,则元素 a 添加成功。
  2. 如果此位置上有其他元素 b(或以链表形式存在多个元素),则比较元素 a 与元素 b 的哈希值:
    1. 如果哈希值不相同,则 a 元素添加成功------>情况2
    2. 如果哈希值相同,则进而需要调用元素 a 所在类的equals()方法:
      1. equals()返回true,元素 a 添加失败
      2. equals()返回false,则元素 a 添加成功------>情况3

对于添加成功的情况2与情况3而言,元素 a 与已经存在指定索引位置上的数据以链表的方式存储。
jdk7:元素 a 放到数组中,指向原来的元素
jdk8:原来的元素在数组中,指向元素 a

总结:七上八下

HashSet底层结构:数组+链表

三、LinkedHashSet

遍历的时候,按照添加的顺序遍历

LinkedHashSet作为HashSet的子类,在添加数据的同时,每个数据还维护了两个引用,记录此数据的前一个数据和后一个数据(双向链表):

优点:对于频繁的遍历操作,LinkedHashSet的效率比HashSet高

四、TreeSet

  1. 向TreeSet中添加的数据,要求是相同类的对象
  2. 两种排序方法:自然排序(实现Comparable接口)、定制排序(Comparator)
  3. 自然排序中,比较两个对象是否相同的标准为:compareTo()返回0,不再是equals()
  4. 定制排序中,比较两个对象是否相同的标准为:compara()返回0,不在是equals()
posted @ 2021-11-19 23:45  叁玖贰拾柒  阅读(10)  评论(0)    收藏  举报