首页 > 其他分享 >集合:Set

集合:Set

时间:2024-08-06 14:51:59浏览次数:9  
标签:Set LinkedHashSet HashSet 元素 集合 TreeSet

Set集合

概念

在 Java 中,Set 是集合框架中的一种接口,它表示不允许包含重复元素的集合。Set 接口继承自 Collection 接口,它没有提供额外的方法,但是它保证了集合中不会包含相同的元素。Set 接口的主要实现类有 HashSet、LinkedHashSet、TreeSet 等。

特点

  • 无序:Set 不保证元素的顺序,即元素不按照特定的顺序存储和访问。
  • 不可重复:不允许包含重复的元素。如果试图向 Set 中添加已经存在的元素,add 方法将返回 false。
  • 无索引:没有带索引的方法,所以不能使用普通for循环遍历,也不能通过索引来获取元素。

HashSet(掌握)

概念

HashSet 是 Java 中的一个集合类,它实现了 Set 接口。Set 是一种不允许包含重复元素的集合,而 HashSet 则是 Set 接口的一个具体实现。因此,HashSet 用于存储一组唯一的元素,不允许重复。

特点

  • 不允许重复元素:如果试图向 HashSet 中添加重复的元素,重复元素将被忽略。
  • 无序性:HashSet 不保证元素的顺序,元素在 HashSet 中是无序的。
  • 允许 null 元素:HashSet 可以包含一个 null 元素。

创建和初始化 HashSet

要使用 HashSet,首先需要创建一个 HashSet 对象。可以使用以下方式进行创建和初始化:

创建空的 HashSet
Set<String> set = new HashSet<>();

创建包含元素的 HashSet
Set<Integer> numbers = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));

基本操作

添加元素

要向 HashSet 中添加元素,可以使用 add() 方法:

Set<String> colors = new HashSet<>();
colors.add("红色");
colors.add("绿色");
colors.add("蓝色");

删除元素

要从 HashSet 中删除元素,可以使用 remove() 方法:

Set<String> fruits = new HashSet<>(Arrays.asList("苹果", "香蕉", "橙子"));
fruits.remove("香蕉");

判断元素是否存在

可以使用 contains() 方法来检查元素是否存在于 HashSet 中:

Set<String> animals = new HashSet<>(Arrays.asList("狗", "猫", "鸟"));
boolean containsCat = animals.contains("猫");

获取集合大小

要获取 HashSet 中元素的数量,可以使用 size() 方法:

Set<Integer> numbers = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));
int size = numbers.size();

遍历 HashSet

遍历 HashSet 中的元素可以使用迭代器或增强型 for 循环。以下是两种遍历方式的示例:

使用迭代器遍历
Set<String> colors = new HashSet<>(Arrays.asList("红色", "绿色", "蓝色"));
Iterator<String> iterator = colors.iterator();

while (iterator.hasNext()) {
    String color = iterator.next();
    System.out.println(color);
}

使用增强型 for 循环遍历
Set<Integer> numbers = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));

for (int number : numbers) {
    System.out.println(number);
}

TreeSet(掌握)

概念

TreeSet 是 Java 集合框架中的一种有序集合,它实现了 Set 接口,因此具有不允许重复元素的特性。与 HashSet 不同,TreeSet 使用红黑树数据结构来存储元素,这使得元素在集合中保持有序。

特点

  • 有序性(Order):TreeSet 中的元素按照自然排序(元素的自然顺序)或者指定的排序方式(通过比较器)排列。这意味着您可以遍历 TreeSet 得到的元素是按照一定的顺序排列的。

  • 唯一性(Uniqueness):与 HashSet 一样,TreeSet 也保证元素的唯一性,不允许重复元素。

因此,TreeSet 是一个适用于需要有序存储唯一元素的场景的理想选择

TreeSet 的内部实现

要深入理解 TreeSet,我们需要了解它的内部实现机制,即红黑树。红黑树是一种自平衡二叉搜索树(Self-Balancing Binary Search Tree),它具有以下特性:

  • 每个节点要么是红色,要么是黑色。

  • 根节点是黑色。

  • 每个叶子节点(NIL 节点,空节点)是黑色的。

  • 如果一个节点是红色的,则它的两个子节点都是黑色的。

  • 从任意节点到其每个叶子节点的所有路径都包含相同数目的黑色节点。

这些规则确保了树的平衡,从而保证了树的高度不会过高,使得查找、插入和删除操作的性能稳定。

在 TreeSet 中,元素被存储在红黑树的节点中,根据元素的大小关系构建树结构。这意味着,插入、删除和查找操作的时间复杂度为 O(log n),其中 n 是集合中的元素个数。由于红黑树的平衡性质,这些操作的性能是可预测的。

TreeSet 的创建与初始化

默认构造函数

使用默认构造函数创建一个空的 TreeSet 对象:

TreeSet<String> treeSet = new TreeSet<>();

指定排序方式的构造函数

您可以使用带有 Comparator 参数的构造函数来指定元素的排序方式。比如,创建一个降序排列的 TreeSet

TreeSet<Integer> customOrderTreeSet = new TreeSet<>(Comparator.reverseOrder());

从现有集合创建

您还可以从现有的集合(如 ListSet)创建一个 TreeSet,以便在不同集合类型之间进行转换:

Set<String> existingSet = new HashSet<>(Arrays.asList("A", "B", "C"));
TreeSet<String> treeSetFromSet = new TreeSet<>(existingSet);

基本操作

添加元素

使用 add 方法来向 TreeSet 中添加元素:

treeSet.add("D");
treeSet.add("E");

删除元素

使用 remove 方法来从 TreeSet 中删除元素:

treeSet.remove("B");

查询元素是否存在

使用 contains 方法来检查元素是否存在于 TreeSet 中:

boolean containsC = treeSet.contains("C");

遍历 TreeSet

使用迭代器遍历
Iterator<String> iterator = treeSet.iterator();
while (iterator.hasNext()) {
    String element = iterator.next();
    System.out.println(element);
}

使用增强的 for 循环遍历
for (String element : treeSet) {
    System.out.println(element);
}

LinkedHashSet(掌握)

概念

LinkedHashSet 是 Java 集合框架中的一种类,它继承自 HashSet,因此具有哈希表的查找性能,同时又使用链表维护元素的插入顺序

特点

  • 有序性(Order)LinkedHashSet 会保持元素的插入顺序,即元素被添加到集合中的顺序就是它们在集合中的顺序。
  • 唯一性(Uniqueness):与 HashSet 一样,LinkedHashSet 保证元素的唯一性,不允许重复元素。

因此,LinkedHashSet 是一个适用于需要按照插入顺序存储唯一元素的场景的理想选择。

LinkedHashSet 的创建与初始化

默认构造函数
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>();

指定容量和加载因子
int initialCapacity = 20;
float loadFactor = 0.5f;
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>(initialCapacity, loadFactor);

从现有集合创建

还可以从现有的集合(如 ListSet)创建一个 LinkedHashSet,以便在不同集合类型之间进行转换:

Set<String> existingSet = new HashSet<>(Arrays.asList("A", "B", "C"));
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>(existingSet);

基本操作

添加元素

使用 add 方法来向 LinkedHashSet 中添加元素:

linkedHashSet.add("D");
linkedHashSet.add("E");

删除元素

使用 remove 方法来从 LinkedHashSet 中删除元素:

linkedHashSet.remove("B");

查询元素是否存在

使用 contains 方法来检查元素是否存在于 LinkedHashSet 中:

boolean containsC = linkedHashSet.contains("C");

遍历 LinkedHashSet

使用迭代器遍历
Iterator<String> iterator = linkedHashSet.iterator();
while (iterator.hasNext()) {
    String element = iterator.next();
    System.out.println(element);
}

使用增强的 for 循环遍历
for (String element : linkedHashSet) {
    System.out.println(element);
}

注意事项

在使用 LinkedHashSet 时,有一些注意事项需要考虑:

  • LinkedHashSet 是线程不安全的,如果在多线程环境中使用,需要考虑线程同步的问题,或者考虑使用线程安全的集合类如 ConcurrentLinkedHashSet。
  • LinkedHashSet 允许存储一个 null 元素,但通常建议避免将 null 作为有效元素存储,以免混淆和错误。
  • 当使用自定义对象作为 LinkedHashSet 元素时,需要正确实现 hashCode() 和 equals() 方法,以确保对象在集合中的唯一性和正确性。
  • LinkedHashSet 的性能通常是很高的,但在处理大量数据时,应注意负载因子的设置,以避免频繁的扩容操作。

EnumSet(了解)

EnumSet是专门为枚举类涉及的集合类

  • EnumSet的所有元素都必须是指定枚举类型的枚举值

  • EnumSet的集合元素是有序的()由枚举类的定义顺序决定存储顺序

  • EnumSet在内部采用位向量形式存储–存储紧凑、高效,占用内存小、运行效率高,适合批量操作

  • EnumSet不允许添加重复元素,如果添加重复值,则会将上一次的值覆盖

  • 不允许添加null,如果添加null,则会报空指针异常NullPointerException

CopyOnWriteArraySet(了解)

  • CopyOnWriteArraySet继承于AbstractSet,这就意味着它是一个集合

  • CopyOnWriteArraySet包含CopyOnWriteArrayList对象,它是通过CopyOnWriteArrayList实现的,而CopyOnWriteArrayList本质是个动态数组队列

  • 所以CopyOnWriteArraySet相当于通过通过动态数组实现的“集合”!

  • CopyOnWriteArrayList中允许有重复的元素;但是,CopyOnWriteArraySet是一个集合,所以它不能有重复集合

  • 因此,CopyOnWriteArrayList额外提供了addIfAbsent()和addAllAbsent()这两个添加元素的API,通过这些API来添加元素时,只有当元素不存在时才执行添加操作!

  • 至于CopyOnWriteArraySet的“线程安全”机制,和CopyOnWriteArrayList一样,是通过volatile和互斥锁来实现的。

标签:Set,LinkedHashSet,HashSet,元素,集合,TreeSet
From: https://www.cnblogs.com/clswhde/p/18345112

相关文章

  • Java集合:Collection and Map;ArrayList;LinkList;HashSet;TreeSet;HashMap;TreeMap;Iterator:
        集合介绍:                        是一组变量类型(容器),跟数组很像。一,引用集合的原因(必要性):                  A:数组的空间长度固定,一旦确定不可以更改。多了浪费,少了报错。          B:使用数......
  • 集合泛型,集合遍历,集合工具类
    集合泛型,集合遍历,集合工具类一.集合泛型在Java中,集合泛型(CollectionGenerics)是Java泛型(Generics)在集合框架(CollectionsFramework)中的一个重要应用。泛型提供了一种编译时类型安全检测机制,允许程序员在编译时期而不是运行时检查非法的类型。当将泛型应用于集合时,可以指定集合......
  • 集合泛型
    Java集合框架中的泛型是Java5引入的一个特性,它允许开发者在编译时就确定集合中元素的类型,从而避免类型转换和潜在的类型安全问题。以下是一些常用的Java集合类和它们使用泛型的例子:ArrayList-动态数组,提供快速随机访问。ArrayList<String>list=newArrayList<>();......
  • 集合
    集合1.集合框架类结构图2.List接口Java中的List接口是Java集合框架(JavaCollectionsFramework)的一部分,它继承自Collection接口。List接口用于表示一个有序的集合,它可以包含重复的元素。与Set接口不同,List保留了元素的插入顺序,并且允许通过索引访问元素。主要特点有序:元素......
  • List,Set,Queue,Map接口
    List,Set,Queue,Map接口一.List接口List接口是Java集合框架中的一个重要接口,它继承自Collection接口。List接口表示一个有序的集合,其中的元素可以重复。这意味着在List中,每个元素都有一个特定的索引位置,我们可以通过这个索引来访问或操作元素。List接口的主要特点包括......
  • 集合遍历
    集合遍历目录集合遍历传统的for循环遍历,基于计数器的:迭代器遍历,Iterator:foreach循环遍历:Stream流处理传统的for循环遍历,基于计数器的:​遍历者自己在集合外部维护一个计数器,然后依次读取每一个位置的元素,当读取到最后一个元素后,停止。主要就是需要按元素的位置来读取元素......
  • 集合工具类
    集合工具类目录集合工具类java.until.Collections类java.util.Arrays类java.util.Properties类java.until.Collections类概念java.util.Collections是集合工具类,用来对集合进行操作常用方法staticvoidshuffle(List<?>list)//打乱集合中元素顺序sort(List<T>list)......
  • 集合泛型
    集合泛型在Java中,泛型(Generics)是一种强大的特性,它允许程序员在编译时进行类型安全检查。当泛型应用于集合时,可以确保集合中只能存储指定类型的元素,从而避免了类型转换的错误和运行时异常。泛型的基本使用泛型在使用时通常遵循以下格式:GenericClass<Type>object=newGeneri......
  • 集合工具类
    集合工具类集合工具类在Java中主要指的是java.util.Collections和java.util.Arrays,以及java.util.stream.Collectors(Java8及以上版本)。以下是对这些工具类的简要说明:1.java.util.CollectionsCollections类提供了一系列静态方法来操作或返回集合对象,包括:排序:sort(),sort(......
  • 集合框架类结构图
    集合框架类结构图集合接口(Collection)Collection:是所有集合的根接口,提供操作集合的基本方法,如add、remove、contains、size、isEmpty等。子接口List:一个有序的集合,可以包含重复的元素。ArrayList:基于动态数组实现,支持快速随机访问。LinkedList:基于链表实现,适合进行频......