首页  >  文章  >  Java  >  Java 集合的终极指南:揭开这个不起眼的数据结构的每一个秘密

Java 集合的终极指南:揭开这个不起眼的数据结构的每一个秘密

Susan Sarandon
Susan Sarandon原创
2024-11-21 00:39:16315浏览

The Ultimate Guide to Sets in Java: Uncovering Every Secret of This Humble Data Structure

嘿,Java 爱好者!无论您是试图找出集合存在原因的编码新手,还是身经百战的程序员想知道是否还有更多东西需要学习,本指南都适合您。我们将深入探讨 Java 中 Set 的所有内容,从其核心目的到复杂的工作原理。系好安全带!


什么是集合?

首先要做的事情是:什么是 Set,我们为什么要关心?从本质上讲,Set 是一个不能包含重复元素的集合。换句话说,集合中的每个项目都与您的自定义模因集合一样独特。

为什么要使用一套?

想象一下,您的任务是为聚会创建宾客名单。您要确保没有人收到两次邀请(因为这很尴尬)。 进入集合。对于 Set,Java 自动确保所有元素都是不同的。它非常适合需要独特性的情况。

集合的特征

  • 不允许重复:Set 最重要的特征是它从不允许重复元素。添加一个已经存在的元素? Java 礼貌地拒绝(不像你的老板有更多的工作)。

  • 无序(通常):集合与列表不同,不关心插入顺序。只要保持独特性,他们就会很高兴。

  • Null 处理 :某些 Set 允许 null 作为元素,但仅限一次。


Java 中的集合类型

现在我们知道了 Set 的作用,让我们看看 Java 提供了哪些类型的 Set:

  1. 哈希集
    • 目的:大多数用例的首选设置。
  • 特性:在 HashMap 的支持下,HashSet 可以快速高效地检查元素是否存在(大多数操作的时间复杂度为 O(1))。

  • 内存布局:在底层使用哈希表,其中基于哈希函数存储元素。

  • 允许空值吗?:可以,但只能有一个。

  • 代码示例 :

Set<String> hashSet = new HashSet<>();
hashSet.add("Apple");
hashSet.add("Banana");
hashSet.add("Apple"); // This will be ignored
System.out.println(hashSet); // Output: [Apple, Banana]
  1. LinkedHashSet
    • 用途:如果您需要一个维护插入顺序的 Set。
  • 特性:HashSet 和 LinkedList 的混合体。

  • 内存布局

    :使用哈希表和双向链表来维护顺序。

  • 代码示例

    :

Set<String> hashSet = new HashSet<>();
hashSet.add("Apple");
hashSet.add("Banana");
hashSet.add("Apple"); // This will be ignored
System.out.println(hashSet); // Output: [Apple, Banana]
  1. 树集
    • 用途:以排序顺序存储元素的Set。
  • 特点:实现NavigableSet,使用红黑树进行存储。

  • 内存布局:平衡的树结构。

  • 代码示例 :

Set<String> linkedHashSet = new LinkedHashSet<>();
linkedHashSet.add("Apple");
linkedHashSet.add("Banana");
linkedHashSet.add("Orange");
System.out.println(linkedHashSet); // Output: [Apple, Banana, Orange]

哈希集如何工作?

让我们掀起引擎盖看看里面。 HashSet 使用 哈希表 进行存储,其中每个元素根据其哈希码分配一个存储桶。添加元素时会发生以下情况:

  1. 哈希码计算 :Java 调用 hashCode() 方法获取元素的哈希码。

  2. 桶确定 :将哈希码映射到桶(数组索引)。

  3. 碰撞处理:如果存储桶已经被占用(碰撞),Java 使用 chaining(较新的 Java 版本中的链表或平衡树)来管理中的多个元素同一个桶。
    HashSet结构图:

Set<Integer> treeSet = new TreeSet<>();
treeSet.add(42);
treeSet.add(10);
treeSet.add(25);
System.out.println(treeSet); // Output: [10, 25, 42]

使用集合的技巧

如果您知道正确的技巧,使用集合会很有趣:

  1. 两个集合的并集
[0] -> [Apple] -> [Banana] 
[1] -> [Grapes]
[2] -> [null]
[3] -> [Orange]
...
  1. 两个集合的交集
Set<Integer> set1 = new HashSet<>(Arrays.asList(1, 2, 3));
Set<Integer> set2 = new HashSet<>(Arrays.asList(3, 4, 5));
set1.addAll(set2);
System.out.println(set1); // Output: [1, 2, 3, 4, 5]
  1. 各组之间的差异
Set<Integer> set1 = new HashSet<>(Arrays.asList(1, 2, 3));
Set<Integer> set2 = new HashSet<>(Arrays.asList(3, 4, 5));
set1.retainAll(set2);
System.out.println(set1); // Output: [3]

何时使用套装?

常见场景

  • 确保应用程序中唯一的用户名

  • 在网络爬虫中跟踪 访问过的页面

  • 维护独特的项目集合(例如,选举中的独特选民)。
    需要考虑的危险信号

  • 如果您需要通过索引访问元素,Set 不是您的朋友。请改用列表。

  • 如果您需要重复项(例如,计算项目的出现次数),请考虑列表或地图。

Set 接口中的方法

这是最常用方法的备忘单:

  • add(E e) :如果元素尚不存在,则添加该元素。

  • remove(Object o) :删除指定元素(如果存在)。

  • contains(Object o) :检查某个元素是否在 Set 中。

  • size() :返回元素的数量。

  • clear() :删除所有元素。

  • isEmpty() :检查 Set 是否为空。

  • iterator() :返回元素上的迭代器。


先进的技术和技巧

  1. 集合中的自定义对象: 始终重写自定义对象的 equals() 和 hashCode() 以确保 Set 的行为符合预期。
Set<String> hashSet = new HashSet<>();
hashSet.add("Apple");
hashSet.add("Banana");
hashSet.add("Apple"); // This will be ignored
System.out.println(hashSet); // Output: [Apple, Banana]
  1. 并发集 :
    使用 ConcurrentHashMap.newKeySet() 或 CopyOnWriteArraySet 进行线程安全操作。

  2. 不可变集 :
    使用 Collections.unmodifyingSet() 或 Set.of() 创建只读集。

Set<String> linkedHashSet = new LinkedHashSet<>();
linkedHashSet.add("Apple");
linkedHashSet.add("Banana");
linkedHashSet.add("Orange");
System.out.println(linkedHashSet); // Output: [Apple, Banana, Orange]

性能考虑因素

HashSet 是大多数任务的最佳选择,因为它在添加、删除和检查元素方面具有 O(1) 性能。 TreeSet 具有较高的成本 (O(log n)),但增加了自然排序的好处。 LinkedHashSet 给出了可预测的迭代顺序,并且开销很小。

识别适合 Set 的问题

认识问题类型 :

  • 唯一性检查(例如,查找文档中的唯一单词)。

  • 设置操作(例如,查找用户之间的共同好友)。

  • 快速查找,不重复(例如,在恒定时间内检查元素是否存在)。

最后的想法

虽然集合可能不像列表那样迷人,也不像地图那样神秘,但它们在有效维护唯一集合方面发挥着至关重要的作用。他们是无名英雄,可确保您的数据保持干净和独特,使您免于那些可能导致意外结果的讨厌的重复。无论您是在优化算法、确保数据完整性,还是只是尝试选择一个的结构只是有效,从内到外理解集合将使您成为更强大的开发人员。因此,充满信心地继续编码,知道您已经释放了强大集合的真正潜力!


这是一个包装,伙计们!

以上是Java 集合的终极指南:揭开这个不起眼的数据结构的每一个秘密的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn