Set集合
一.特点
- 不能重复
- 没有顺序
- 没有索引
二.Set集合的实现类
1.HashSet:无序,不可重复,无索引
- HashSet集合的底层采用哈希表存储数据的
- 哈希表是一种对与增删改查数据性能都较好的结构
哈希表的组成:
- jdk8之前:底层使用的数组+链表组成
- jdk8之后:底层采用的是数组+链表+红黑树组成
哈希值:
- 是jdk根据对象的出的存储的地址,按照某种规则算出来的int类型的数值
哈希值的特点:
- 对同一个对象多次调用hasCode()方法,返回的哈希值是相同的
- 默认情况下:不同对象的哈希值是不同的
hashSet底层的存储结构:
- 当我们调用无参构造创建hashSet集合的时候,默认创建一个长度为16的素组
- 添加元素时,根据元素的哈希值与数组的长度进行计算,从而得出元素对应的存储位置.
- 判断当前计算出的元素是否为null,如果为null,直接存入
- 如果不为null,表示铀元素,需要调用equals方法比较
jdk8以前:新元素占据旧元素的位置,指向旧元素
jdk8及以后:新元素挂在旧元素的下边
jdk8及以后的版本底层原理:
- 底层结构:哈希表(数组,链表,红黑树结合)
- 当挂在元素下边的数据过多的时候,查询的性能都降低,从jdk8开始,当链表的长度超过8的时候,自动的将链表转换为红黑树
- 红黑树的引入进一步提高了数据的操作能力
hashSet去重原理
首先判断元素的hashcode值是否相同,如果不同,则不重复;如果相同,则需要进一步调用他的equals()
方法进行比较,如果返回的true则认为元素重复,不存;否则呗则认为不同,挂在元素的下边。
案例:
2.LinkedHashSet:
- 特点:有序,不可重复,无索引
- 有序:指的是存入的和取出的顺序一致
3.TreeSet:可排序(不是有序),不重复,无索引
TreeSet是Java中的一个集合类,它实现了SortedSet接口,并且使用红黑树(Red-Black Tree)数据结构来存储元素,能够保证元素在集合中的顺序。
以下是TreeSet的一些关键知识点:
- TreeSet的特点:
- 元素有序
- 元素唯一
- 支持自然排序和自定义排序
- 内部使用红黑树实现
- TreeSet的常用方法:
- add():添加元素
- remove():移除元素
- size():获取元素数量
- clear():清空集合
- first():获取第一个元素
- last():获取最后一个元素
- contains():判断是否包含元素
- iterator():获取迭代器
- TreeSet的排序:
- 自然排序:使用元素自身的比较方法进行排序,元素需要实现Comparable接口。
- 自定义排序:通过传入一个Comparator对象来实现排序,Comparator对象负责元素之间的比较。
- TreeSet的实现原理:
- 内部使用红黑树实现,红黑树是一种自平衡二叉查找树,能够保证在最坏情况下也能达到O(logn)的时间复杂度。
- 元素插入时,根据元素的比较结果插入到合适的位置。
- 元素删除时,将待删除节点标记为删除状态,不会立即删除,避免破坏树的平衡,同时在需要时进行删除。
- TreeSet的性能:
- 查找、插入、删除元素的时间复杂度均为O(logn),性能优于ArrayList和LinkedList。
- TreeSet在使用自定义比较器时,性能可能会略低于使用自然排序的情况。
总之,TreeSet提供了一种有序且唯一的集合存储方式,使用红黑树实现高效的元素查找、插入、删除等操作,并支持自然排序和自定义排序。对于需要进行排序和去重的数据,TreeSet是一个不错的选择。
常用API
以下是一些常用的Set集合方法及其作用:
add(E e)
: 向Set集合中添加元素e,如果集合中已经存在该元素,则不会添加。
javaCopy code
Set<String> set = new HashSet<>();
set.add("apple");
set.add("banana");
set.add("apple");
System.out.println(set); // 输出结果为 [banana, apple]
remove(Object o)
: 从Set集合中删除元素o,如果元素o不存在于集合中,则不会进行任何操作。
javaCopy code
Set<String> set = new HashSet<>();
set.add("apple");
set.add("banana");
set.remove("apple");
System.out.println(set); // 输出结果为 [banana]
contains(Object o)
: 判断Set集合中是否包含元素o,如果包含则返回true,否则返回false。
javaCopy code
Set<String> set = new HashSet<>();
set.add("apple");
set.add("banana");
System.out.println(set.contains("apple")); // 输出结果为 true
System.out.println(set.contains("orange")); // 输出结果为 false
size()
: 获取Set集合中元素的个数。
javaCopy code
Set<String> set = new HashSet<>();
set.add("apple");
set.add("banana");
System.out.println(set.size()); // 输出结果为 2
isEmpty()
: 判断Set集合是否为空,如果为空则返回true,否则返回false。
javaCopy code
Set<String> set = new HashSet<>();
System.out.println(set.isEmpty()); // 输出结果为 true
set.add("apple");
System.out.println(set.isEmpty()); // 输出结果为 false
clear()
: 清空Set集合中的所有元素。
javaCopy code
Set<String> set = new HashSet<>();
set.add("apple");
set.add("banana");
System.out.println(set); // 输出结果为 [banana, apple]
set.clear();
System.out.println(set); // 输出结果为 []
iterator()
: 返回Set集合的迭代器,可以用来遍历Set集合中的所有元素。