Java LinkedHashSet

LikedHashSet 是保存了元素插入顺序的有序的 Set 集合。在本教程中,我们将借助示例学习 Java LinkedHashSet 类及其方法。

在本教程中,我们将借助示例学习 Java LinkedHashSet 类及其方法。

LinkedHashSet 是保存了元素插入顺序的有序的 Set 集合。 LinkedHashSet 实现了 Set 接口,其内部使用 LinkedHashMap 实现。 LinkedHashSet 中元素都保存内部的 LinkedHashMap 的键中。 LinkedHashMap 内部通过一个双向链表维持元素的插入顺序。

LinkedHashSetHashSet 相似,只是 HashSet 不保证元素的顺序,而 LinkedHashSet 按元素的插入顺序保存元素。

创建 LinkedHashSet

我们导入 java.util.LinkedHashSet 类后,就可以通过构造方法创建 LinkedHashSet 对象了。例如:

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

这里, Type 是 LinkedHashSet 中的元素的数据类型。

LinkedHashSet 构造函数

LinkedHashMap 重载了 4 个构造方法:

LinkedHashSet()
LinkedHashSet(int initialCapacity)
LinkedHashSet(int initialCapacity, float loadFactor)
LinkedHashSet(Collection<? extends E> c)

参数说明:

  • initialCapacity: 初始容量

    底层 LinkedHashMap 的初始容量,默认值为 16

  • loadFactor: 负载因子

    底层 LinkedHashMap 的负载因子,默认值 0.75f。用来指示何时对底层容器扩容。

    比如容量时 16, 负载因子 0.75f, 那么使用量超过 16 * 0.75 = 12 的时候,就要扩容。

因为 LinkedHashSet 底层使用了 LinkedHashMap 实现,这两个参数都是为了初始化底层 LinkedHashMap 而传入的。请转到 Java LinkedHashMap 章节了解更多信息。

从其他集合创建 LinkedHashSet

下面是我们如何创建一个包含其他集合的所有元素的链接哈希集。

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

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

    // Creating a LinkedHashSet from an ArrayList
    LinkedHashSet<Integer> numbers = new LinkedHashSet<>(evenNumbers);
    System.out.println("LinkedHashSet: " + numbers);
  }
}

输出

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

LinkedHashSet 的方法

HashSet 完全实现了 Set 接口定义的所有集合操作方法。

向 LinkedHashSet 插入元素

  • add() - 将指定的元素添加到 LinkedHashSet 集合中
  • addAll() - 将指定集合的所有元素添加到 LinkedHashSet 集合中

例如,

import java.util.LinkedHashSet;

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

    evenNumber.add(2);
    evenNumber.add(4);
    evenNumber.add(6);
    System.out.println("LinkedHashSet: " + evenNumber);

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

    numbers.addAll(evenNumber);
    numbers.add(5);
    System.out.println("New LinkedHashSet: " + numbers);
  }
}

输出

LinkedHashSet: [2, 4, 6]
New LinkedHashSet: [2, 4, 6, 5]

LinkedHashSet 迭代器

iterator() 返回一个迭代器,可以迭代当前 LinkedHashSet 对象中的元素。

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

public 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<Integer> iterate = numbers.iterator();

    System.out.print("LinkedHashSet using Iterator: ");

    while (iterate.hasNext()) {
      System.out.print(iterate.next());
      System.out.print(", ");
    }
  }
}

输出

LinkedHashSet: [2, 5, 6]
LinkedHashSet using Iterator: 2, 5, 6,

关于迭代器的更多信息,请转到 Java 迭代器章节查看。

删除元素

  • remove() - 从 LinkedHashSet 集合中删除指定的元素
  • removeAll() - 从 LinkedHashSet 集合中删除由参数指定的另一个集合的所有元素

例如,

import java.util.LinkedHashSet;

public 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);

    boolean value1 = numbers.remove(5);
    System.out.println("Is 5 removed? " + value1);

    boolean value2 = numbers.removeAll(numbers);
    System.out.println("Are all elements removed? " + value2);
  }
}

输出

LinkedHashSet: [2, 5, 6]
Is 5 removed? true
Are all elements removed? true

集合操作

集合的并集

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

import java.util.LinkedHashSet;

public 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("Union is: " + numbers);
  }
}

输出

LinkedHashSet1: [2, 4]
LinkedHashSet2: [1, 3]
Union is: [1, 3, 2, 4]

集合的交集

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

import java.util.LinkedHashSet;

public 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("Intersection is: " + evenNumbers);
  }
}

输出

LinkedHashSet1: [2, 3]
LinkedHashSet2: [2, 4]
Intersection is: [2]

集差

要计算两个集合之间的差集异,我们可以使用 removeAll() 方法。例如,

import java.util.LinkedHashSet;

public 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);

    primeNumbers.removeAll(oddNumbers);
    System.out.println("Difference : " + primeNumbers);
  }
}

输出

LinkedHashSet1: [2, 3, 5]
LinkedHashSet2: [1, 3, 5]
Difference : [2]

子集

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

import java.util.LinkedHashSet;

public 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);

    boolean result = numbers.containsAll(primeNumbers);
    System.out.println("Is LinkedHashSet2 is subset of LinkedHashSet1? " + result);
  }
}

输出

LinkedHashSet1: [1, 2, 3, 4]
LinkedHashSet2: [2, 3]
Is LinkedHashSet2 is subset of LinkedHashSet1? true

LinkedHashSet 的其他方法

  • clone() - 克隆一个 HashSet
  • contains() - 如果 HashSet 包含指定元素,则返回 true
  • isEmpty() - 检查 HashSet 是否为空
  • size() - 返回 HashSet 大小
  • clear() - 清空 HashSet

LinkedHashSet 与 HashSet

LinkedHashSetHashSet 都实现了 Set 接口。但是它们之间存在一些差异。

  • LinkedHashSet 在内部维护一个链表以保持元素的插入顺序。
  • 因为 LinkedHashSet 内部维护着链表,所以 LinkedHashSet 占用的存储空间比 HashSet 多。
  • LinkedHashSetHashSet 性能慢。

请转到 Java HashSet 章节了解更多信息。

LinkedHashSet 与 TreeSet

以下是 LinkedHashSetTreeSet 的主要区别:

  • TreeSet 类实现了 SortedSet 接口,也是一个有序的集合,但是 TreeSet 可自定义排序规则。但是 LinkedHashSet 只维护元素的插入顺序。
  • TreeSet 通常比 LinkedHashSet 慢。这是因为每当 TreeSet 添加一个元素时 ,它都必须执行排序操作。
  • LinkedHashSet 允许插入 null 值。但是, TreeSet 不允许插入 null 值。

请转到 Java TreeSet 章节了解更多信息。