2.3 Set接口
public interface Set<E>
extends Collection<E>
集合中的对象并不能保存重复的对象,也就是说 Set
接口可以储存一组唯一、无序的对象。在Java中,Set
是一种集合接口,它继承自Collection
接口。Set集合的主要属性如下:
唯一性:
Set集合中不允许包含重复的元素。当添加重复元素时,Set集合会自动拒绝并保留唯一性。无序性:
Set集合中的元素是无序排列的,不会按照插入顺序或者其他特定顺序进行存储。这是因为Set集合通常基于哈希表或红黑树实现,以提供快速的插入、删除和搜索操作。不允许使用索引:
Set集合没有提供索引访问元素的方法,因为它的元素是无序的。如果需要按索引访问元素,应该使用List集合。非同步
:set接口的实现类是非线程安全的,不适合在多线程环境中使用需要使用Collections工具提供的方法进行同步操作。
常见的Set集合实现类有:
-
HashSet
:基于哈希表实现,具有较好的查找性能,不保证元素的存储顺序。 -
LinkedHashSet
:基于哈希表和链表实现,按插入顺序保留元素,具有较好的遍历性能。 -
TreeSet
:基于红黑树实现,按照元素的自然顺序或者指定的Comparator进行排序。
of
方法和copyOf
,都是static
方法返回一个不可修改的Set
集合
2.3.1TreeSet 类动态储存数据
public class TreeSet<E>
extends AbstractSet<E>
implements NavigableSet<E>, Cloneable, Serializable
TreeSet
使用红黑树数据结构
来实现元素的排序和储存。TreeSet
中的元素按照自然排序或指定的比较器(Comparator)进行排序,并且不允许重复的元素,不允许 null
元素。
TreeSet
的特性:
- 非线程安全
- 值必须可比较(元素实现 Comparable 接口、传递 比较器 Comparator 对象)
- 不能存 null
- 判断是否是重复元素,是按照自然比较/比较器进行比较
如果使用
无参构造
则 Set 集合中的元素要具备可比较行(实现 Comparable 接口)
如果使用构造(比较器)
则 Set 集合中的元素按照比较器比较顺序排序
常用的构造方法
方法 | 描述 |
---|---|
TreeSet() | 构造一个新的空TreeSet集合,根据其元素的自然顺序进行排序。 |
TreeSet(Comparator<? super E> comparator) | 构造一个新的空TreeSet集合,根据指定的比较器进行排序。 |
TreeSet(Collection<? extends E> c) | 构造一个新的TreeSet集合,该TreeSet集合包含指定集合中的元素,并根据其元素的自然顺序进行排序。 |
常用方法
方法 | 返回值 | 描述 |
---|---|---|
ceiling(E e) | E | 返回此集合中大于或等于给定元素的最小元素,如果没有这样的元素,则返回 null。 |
first() | E | 返回当前在此集合中的第一个(最低的)元素。 |
floor(E e) | E | 返回此集合中小于或等于给定元素的最大元素,如果没有这样的元素,则返回 null。 |
headSet(E toElement) | SortedSet<[E]> | 返回此集合中元素严格小于 toElement 的部分的视图。 |
higher(e) | E | 返回此集合中严格大于给定元素的最小元素,如果没有这样的元素,则返回 null。 |
last() | E | 返回当前在此集合中的最后一个(最高的)元素。 |
lower(e) | E | 返回此集合中严格小于给定元素的最大元素,如果没有这样的元素,则返回 null。 |
pollFirst() | E | 检索并删除第一个(最低的)元素,如果此集合为空,则返回 null。 |
pollLast() | E | 检索并删除最后一个(最高的)元素,如果此集合为空,则返回 null。 |
tailSet(E fromElement) | SortedSet<[E]> | 返回此集合中元素严格大于或等于 fromElement 的部分的视图。 |
请注意,
TreeSet
是SortedSet
接口的实现类,因此它具有一些额外的方法,如first()
、last()
、lower()
、floor()
、higher()
、ceiling()
和subSet()
。这些方法可用于根据元素的自然排序或提供的比较器来执行特定的操作和查询。
示例:
package com.kfm.List.Set;/*
@CreatTime:2023-09-05 21:07
*/
import java.util.*;
public class TreeSetTest {
public static void main(String[] args) {
/*
Set 唯一不重复
TreeSet HashSet LinkedHashSet
TreeSet, 不能存 null。
如果使用 无参构造 则 Set 集合中的元素要具备可比较行(实现 Comparable 接口)
如果使用 构造(比较器) 则 Set 集合中的元素按照比较器比较顺序排序
*/
//Tree按照元素自然排序进行排序,也可以自定义比较器
Set<Object> of = Set.of();
TreeSet<String> set = new TreeSet<>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.length() - o2.length();
}
});
TreeSet<String> set1 = new TreeSet(List.of("null", "a", "a", "b", "c", "e", "f", "g"));
System.out.println(set1); // [a, b, c, e, f, g, null]
// 返回此集合中大于或等于给定元素的最小元素,如果没有这样的元素,则返回null。
String ceiling = set1.ceiling("d");
System.out.println(ceiling);// e
// 返回当前在此集合中的第一个(最低的)元素。
String first = set1.first();
System.out.println(first); // a
// 返回此集合中小于或等于给定元素的最大元素,如果没有这样的元素,则返回null。
String floor = set1.floor("d");
System.out.println(floor); // c
// 返回此集合中元素严格小于toElement的部分的视图。
SortedSet<String> headSet = set1.headSet("c");
System.out.println(headSet); // a, b
// 返回此集合中严格大于给定元素的最小元素,如果没有这样的元素,则返回null。
String higher = set1.higher("c");
System.out.println(higher); // e
// 返回此集合中元素严格大于或等于fromElement的部分的视图。
SortedSet<String> tailSet = set1.tailSet("c");
System.out.println(tailSet); // c, e, f, g, null
// 迭代
for (Object obj : set){
System.out.println(obj);
}
}
}
2.3.2 HashSet 类动态储存数据
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, Serializable
HashSet
的特性:
- 实现了 Set 接口,底层实现是 HashMap 。不保证迭代顺序,允许 null 元素
- 非线程安全的
- 如果 add 的值已存在( equals 方法返回 true ,基本数据类型自动装箱)返回 false
- 如果 HashSet 中存的是对象,需要重写此对象类中的 equals 和 hashCode()
- HashSet内部使用哈希表来存储元素,这使得插入、删除和查找元素的操作效率非常高。如果你需要对集合进行频繁的插入、删除和查找操作,并且不关心元素的顺序,那么HashSet可以提供较好的性能。
- 当需要存储唯一元素、不关心元素顺序、需要快速的插入、删除和查找操作时,选择HashSet是一个不错的选择。
构造方法
构造方法 | 描述 |
---|---|
LinkedHashSet() | 构造一个新的、空的链式哈希集合,具有默认的初始容量(16)和加载因子(0.75)。 |
LinkedHashSet(int initialCapacity) | 构造一个新的、空的链式哈希集合,具有指定的初始容量和默认的加载因子(0.75)。 |
LinkedHashSet(int initialCapacity, float loadFactor) | 构造一个新的、空的链式哈希集合,具有指定的初始容量和加载因子。 |
LinkedHashSet(Collection<? extends E> c) | 构造一个具有与指定集合相同元素的新链式哈希集合。 |
常用方法
方法 | 修饰符和类型 | 描述 |
---|---|---|
spliterator() | Spliterator | 创建一个延迟绑定和快速失败的Spliterator,用于遍历集合的元素。 |
add(E e) | boolean | 将指定元素添加到集合中。 |
clear() | void | 清空集合中的所有元素。 |
clone() | Object | 创建并返回集合的浅拷贝副本。 |
contains(Object o) | boolean | 检查集合是否包含指定元素。 |
isEmpty() | boolean | 判断集合是否为空。 |
iterator() | Iterator | 返回在集合上进行迭代的迭代器。 |
remove(Object o) | boolean | 从集合中移除指定元素。 |
size() | int | 返回集合中的元素数量。 |
toArray() | Object[] | 将集合转换为数组。 |
toArray(T[] a) | T[] | 将集合转换为指定类型的数组。 |
equals(Object o) | boolean | 判断集合是否与指定对象相等。 |
hashCode() | int | 返回集合的哈希码值。 |
removeAll(Collection<?> c) | boolean | 移除集合中与指定集合相同的元素。 |
addAll(Collection<? extends E> c) | boolean | 将指定集合中的所有元素添加到集合中。 |
containsAll(Collection<?> c) | boolean | 判断集合是否包含指定集合中的所有元素。 |
retainAll(Collection<?> c) | boolean | 保留集合中与指定集合相同的元素,移除其他元素。 |
toString() | String | 返回集合的字符串表示形式。 |
forEach(Consumer<? super E> action) | void | 对集合中的每个元素执行指定操作。 |
parallelStream() | Stream | 返回一个并行执行集合操作的Stream。 |
removeIf(Predicate<? super E> filter) | boolean | 删除集合中满足指定条件的所有元素。 |
stream() | Stream | 返回一个顺序执行集合操作的Stream。 |
add(E e) (default) | boolean | 将指定元素添加到集合中。 |
containsAll(Collection<?> c) (default) | boolean | 判断集合是否包含指定集合中的所有元素。 |
public class Repetition1 {
//使用一个List集合存储多个元素。计算集合中共有多少个不重复元素并输出。
public static void main(String[] args) {
List<String> list = List.of("null","a","b","c","a","1","d","e","c");
Set<String> unrepetion = new HashSet<String>(list);
int count = 0;
for(String str : unrepetion){
System.out.println(str);
}
System.out.println("不重复的元素是" +unrepetion.size());
}
}