跳到主要内容

Java LinkedHashSet 类

提示
  1. 结构与实现LinkedHashSet 结合了哈希表和双向链表的特性,维护元素的插入顺序。
  2. 创建和方法:可创建具有指定容量和负载因子的 LinkedHashSet,支持元素的添加、访问、删除等操作。
  3. 特点与使用场景:相比 HashSetLinkedHashSet 需要更多存储空间和时间,适用于需要维护插入顺序的场景。

Java 集合框架的 LinkedHashSet 类提供了哈希表和链表数据结构的功能。

它实现了 Set 接口

Java LinkedHastSet 类实现了 Set 接口。

LinkedHashSet 的元素存储在类似于 HashSet 的哈希表中。

然而,链式哈希集合在其所有元素中内部维护了一个双向链表。这个链表定义了元素插入哈希表的顺序。

创建 LinkedHashSet

为了创建一个链式哈希集合,我们首先必须导入 java.util.LinkedHashSet 包。

一旦我们导入了包,以下是我们在 Java 中创建链式哈希集合的方法。

// 容量为 8 和负载因子为 0.75 的 LinkedHashSet
LinkedHashSet<Integer> numbers = new LinkedHashSet<>(8, 0.75);

这里,我们创建了一个名为 numbers 的链式哈希集合。

注意 new LinkedHashSet<>(8, 0.75) 这部分。这里,第一个参数是 容量,第二个参数是 负载因子

  • 容量 - 这个哈希集合的容量是 8。意味着它可以存储 8 个元素。
  • 负载因子 - 这个哈希集合的负载因子是 0.75。这意味着,每当我们的哈希表填充到 75%,元素就会被移动到一个新的哈希表中,该哈希表的大小是原哈希表的两倍。

默认容量和负载因子

我们可以创建一个没有定义容量和负载因子的链式哈希集合。例如,

// 默认容量和负载因子的 LinkedHashSet
LinkedHashSet<Integer> numbers1 = new LinkedHashSet<>();

默认情况下,

  • 链式哈希集合的容量将是 16
  • 负载因子将是 0.75

从其他集合创建 LinkedHashSet

以下是我们如何创建包含其他集合所有元素的链式哈希集合。

import java.util.LinkedHashSet;
import java.util.ArrayList;

class Main {
public static void main(String[] args) {
// 创建偶数的 ArrayList
ArrayList<Integer> evenNumbers = new ArrayList<>();
evenNumbers.add(2);
evenNumbers.add(4);
System.out.println("ArrayList: " + evenNumbers);

// 从 ArrayList 创建 LinkedHashSet
LinkedHashSet<Integer> numbers = new LinkedHashSet<>(evenNumbers);
System.out.println("LinkedHashSet: " + numbers);
}
}


输出

ArrayList: [2, 4]
LinkedHashSet: [2, 4]

LinkedHashSet 的方法

LinkedHashSet 类提供了允许我们对链式哈希集合执行各种操作的方法。

向 LinkedHashSet 插入元素

  • add() - 向链式哈希集合中插入指定的元素
  • addAll() - 将指定集合的所有元素插入到链式哈希集合中

例如,

import java.util.LinkedHashSet;

class Main {
public static void main(String[] args) {
LinkedHashSet<Integer> evenNumber = new LinkedHashSet<>();

// 使用 add() 方法
evenNumber.add(2);
evenNumber.add(4);
evenNumber.add(6);
System.out.println("LinkedHashSet: " + evenNumber);

LinkedHashSet<Integer> numbers = new LinkedHashSet<>();

// 使用 addAll() 方法
numbers.addAll(evenNumber);
numbers.add(5);
System.out.println("新的 LinkedHashSet: " + numbers);
}
}

输出

LinkedHashSet: [2, 4, 6]
新的 LinkedHashSet: [2, 4, 6, 5]

访问 LinkedHashSet 元素

要访问链式哈希集合的元素,我们可以使用 iterator() 方法。为了使用这个方法,我们必须导入 java.util.Iterator 包。例如,

import java.util.LinkedHashSet;
import java.util.Iterator;

class Main {
public static void main(String[] args) {
LinkedHashSet<Integer> numbers = new LinkedHashSet<>();
numbers.add(2);
numbers.add(5);
numbers.add(6);
System.out.println("LinkedHashSet: " + numbers);

// 调用 iterator() 方法
Iterator<Integer> iterate = numbers.iterator();

System.out.print("使用迭代器的 LinkedHashSet: ");

// 访问元素
while(iterate.hasNext()) {
System.out.print(iterate.next());
System.out.print(", ");
}
}
}

输出

LinkedHashSet: [2, 5, 6]
使用迭代器的 LinkedHashSet: 2, 5, 6,

注意

  • hasNext() 如果链式哈希集合中有下一个元素,则返回 true
  • next() 返回链式哈希集合中的下一个元素

从 HashSet 中移除元素

  • remove() - 从链式哈希集合中移除指定的元素
  • removeAll() - 从链式哈希集合中移除所有元素

例如,

import java.util.LinkedHashSet;

class Main {
public static void main(String[] args) {
LinkedHashSet<Integer> numbers = new LinkedHashSet<>();
numbers.add(2);
numbers.add(5);
numbers.add(6);
System.out.println("LinkedHashSet: " + numbers);

// 使用 remove() 方法
boolean value1 = numbers.remove(5);
System.out.println("5 是否被移除? " + value1);

boolean value2 = numbers.removeAll(numbers);
System.out.println("是否移除了所有元素? " + value2);
}
}

输出

LinkedHashSet: [2, 5, 6]
5 是否被移除? true
是否移除了所有元素? true

集合操作

LinkedHashSet 类的各种方法也可用于执行各种集合操作。

集合的并集

要执行两个集合之间的并集,我们可以使用 addAll() 方法。例如,

import java.util.LinkedHashSet;

class Main {
public static void main(String[] args) {
LinkedHashSet<Integer> evenNumbers = new LinkedHashSet<>();
evenNumbers.add(2);
evenNumbers.add(4);
System.out.println("LinkedHashSet1: " + evenNumbers);

LinkedHashSet<Integer> numbers = new LinkedHashSet<>();
numbers.add(1);
numbers.add(3);
System.out.println("LinkedHashSet2: " + numbers);

// 两个集合的并集
numbers.addAll(evenNumbers);
System.out.println("并集是: " + numbers);
}
}

输出

LinkedHashSet1: [2, 4]
LinkedHashSet2: [1, 3]
并集是: [1, 3, 2, 4]

集合的交集

要执行两个集合之间的交集,我们可以使用 retainAll() 方法。例如

import java.util.LinkedHashSet;

class Main {
public static void main(String[] args) {
LinkedHashSet<Integer> primeNumbers = new LinkedHashSet<>();
primeNumbers.add(2);
primeNumbers.add(3);
System.out.println("LinkedHashSet1: " + primeNumbers);

LinkedHashSet<Integer> evenNumbers = new LinkedHashSet<>();
evenNumbers.add(2);
evenNumbers.add(4);
System.out.println("LinkedHashSet2: " + evenNumbers);

// 两个集合的交集
evenNumbers.retainAll(primeNumbers);
System.out.println("交集是: " + evenNumbers);
}
}

输出

LinkedHashSet1: [2, 3]
LinkedHashSet2: [2, 4]
交集是: [2]

集合的差集

要计算两个集合之间的差集,我们可以使用 removeAll()

方法。例如,

import java.util.LinkedHashSet;

class Main {
public static void main(String[] args) {
LinkedHashSet<Integer> primeNumbers = new LinkedHashSet<>();
primeNumbers.add(2);
primeNumbers.add(3);
primeNumbers.add(5);
System.out.println("LinkedHashSet1: " + primeNumbers);

LinkedHashSet<Integer> oddNumbers = new LinkedHashSet<>();
oddNumbers.add(1);
oddNumbers.add(3);
oddNumbers.add(5);
System.out.println("LinkedHashSet2: " + oddNumbers);

// LinkedHashSet1 和 LinkedHashSet2 之间的差集
primeNumbers.removeAll(oddNumbers);
System.out.println("差集 : " + primeNumbers);
}
}

输出

LinkedHashSet1: [2, 3, 5]
LinkedHashSet2: [1, 3, 5]
差集: [2]

子集

要检查一个集合是否是另一个集合的子集,我们可以使用 containsAll() 方法。例如,

import java.util.LinkedHashSet;

class Main {
public static void main(String[] args) {
LinkedHashSet<Integer> numbers = new LinkedHashSet<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
numbers.add(4);
System.out.println("LinkedHashSet1: " + numbers);

LinkedHashSet<Integer> primeNumbers = new LinkedHashSet<>();
primeNumbers.add(2);
primeNumbers.add(3);
System.out.println("LinkedHashSet2: " + primeNumbers);

// 检查 primeNumbers 是否是 numbers 的子集
boolean result = numbers.containsAll(primeNumbers);
System.out.println("LinkedHashSet2 是否是 LinkedHashSet1 的子集? " + result);
}
}

输出

LinkedHashSet1: [1, 2, 3, 4]
LinkedHashSet2: [2, 3]
LinkedHashSet2 是否是 LinkedHashSet1 的子集? true

LinkedHashSet 的其他方法

方法描述
clone()创建 LinkedHashSet 的副本
contains()搜索 LinkedHashSet 中的指定元素,并返回布尔结果
isEmpty()检查 LinkedHashSet 是否为空
size()返回 LinkedHashSet 的大小
clear()LinkedHashSet 中移除所有元素

要了解更多关于 LinkedHashSet 方法的信息,可以访问 Java LinkedHashSet(官方 Java 文档)

LinkedHashSet 与 HashSet 的比较

LinkedHashSetHashSet 都实现了 Set 接口。然而,它们之间存在一些差异。

  • LinkedHashSet 内部维护了一个链表。因此,它维护了元素的插入顺序。
  • LinkedHashSet 类比 HashSet 需要更多的存储空间。这是因为 LinkedHashSet 内部维护了链表。
  • LinkedHashSet 的性能比 HashSet 慢。这是由于 LinkedHashSet 中存在的链表。

LinkedHashSet 与 TreeSet 的比较

以下是 LinkedHashSetTreeSet 之间的主要区别:

  • TreeSet 类实现了 SortedSet 接口。因此,树集合中的元素是排序的。然而,LinkedHashSet 类只维护其元素的插入顺序。
  • TreeSet 通常比 LinkedHashSet 慢。这是因为每当一个元素被添加到 TreeSet 时,它必须执行排序操作。
  • LinkedHashSet 允许插入空值。然而,我们不能向 TreeSet 中插入空值。