如何在 Java 中检查集合是否包含重复元素

JavaJavaBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

在这个实验中,你将学习如何高效地检查 Java 集合中是否存在重复元素。我们将探索使用 HashSet(Java 集合框架中的一个强大工具)来识别重复元素。

通过实际操作步骤,你将首先学习如何利用 HashSet 的元素唯一性特性来检测重复元素。然后,你将发现另一种方法,即比较原始集合和由其创建的 HashSet 的大小。最后,我们将探讨在检查重复元素时如何处理空元素。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL java(("Java")) -.-> java/DataStructuresGroup(["Data Structures"]) java(("Java")) -.-> java/ObjectOrientedandAdvancedConceptsGroup(["Object-Oriented and Advanced Concepts"]) java/DataStructuresGroup -.-> java/arrays("Arrays") java/DataStructuresGroup -.-> java/collections_methods("Collections Methods") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/arraylist("ArrayList") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/hashset("HashSet") subgraph Lab Skills java/arrays -.-> lab-559941{{"如何在 Java 中检查集合是否包含重复元素"}} java/collections_methods -.-> lab-559941{{"如何在 Java 中检查集合是否包含重复元素"}} java/arraylist -.-> lab-559941{{"如何在 Java 中检查集合是否包含重复元素"}} java/hashset -.-> lab-559941{{"如何在 Java 中检查集合是否包含重复元素"}} end

使用 HashSet 检查重复元素

在这一步中,我们将探索如何在 Java 中使用 HashSet 来高效地检查集合中是否存在重复元素。HashSet 是 Java 集合框架的一部分,它特别有用,因为它存储唯一元素,并且查找速度非常快。

首先,在你的 ~/project 目录下创建一个名为 DuplicateCheck.java 的新 Java 文件。你可以直接在 WebIDE 文件资源管理器中,右键单击文件列表区域,选择“新建文件”,然后输入 DuplicateCheck.java 来完成此操作。

现在,在代码编辑器中打开 DuplicateCheck.java 文件,并添加以下代码:

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class DuplicateCheck {

    public static void main(String[] args) {
        // Create a list with some duplicate elements
        List<String> names = new ArrayList<>();
        names.add("Alice");
        names.add("Bob");
        names.add("Alice"); // Duplicate
        names.add("Charlie");
        names.add("Bob"); // Duplicate

        System.out.println("Original List: " + names);

        // Use a HashSet to find duplicates
        Set<String> uniqueNames = new HashSet<>();
        Set<String> duplicates = new HashSet<>();

        for (String name : names) {
            if (!uniqueNames.add(name)) {
                // If add returns false, the element is already in the set
                duplicates.add(name);
            }
        }

        System.out.println("Duplicates found: " + duplicates);
    }
}

让我们来详细分析这段代码的新部分:

  • import java.util.ArrayList;import java.util.HashSet;import java.util.List;import java.util.Set;:这些行从 Java 实用工具库中导入了处理列表和集合所需的类。
  • List<String> names = new ArrayList<>();:这行代码创建了一个名为 namesList,它可以存储 String 对象。我们使用 ArrayList 作为 List 接口的具体实现。
  • names.add(...):这行代码向我们的 names 列表中添加元素。注意,"Alice" 和 "Bob" 被添加了两次。
  • Set<String> uniqueNames = new HashSet<>();:这行代码使用 HashSet 实现创建了一个名为 uniqueNamesSetSet 保证只包含唯一元素。
  • Set<String> duplicates = new HashSet<>();:这行代码创建了另一个 Set,用于存储我们找到的重复元素。
  • for (String name : names):这是一个 for-each 循环,用于遍历 names 列表中的每个 name
  • if (!uniqueNames.add(name))HashSetadd() 方法在元素成功添加(即该元素不在集合中)时返回 true,如果元素已经存在则返回 false! 对结果取反,因此 if 块内的代码仅在 add() 返回 false 时执行,这表明存在重复元素。
  • duplicates.add(name);:如果找到重复元素,我们将其添加到 duplicates 集合中。

保存 DuplicateCheck.java 文件(Ctrl + S 或 Cmd + S)。

现在,打开 WebIDE 底部的终端。确保你位于 ~/project 目录下。你可以通过输入 pwd 并按回车键来确认。输出应该是 /home/labex/project

使用 javac 命令编译 Java 程序:

javac DuplicateCheck.java

如果没有错误,你应该看不到输出。这意味着编译成功,并且在 ~/project 目录下已经创建了一个 DuplicateCheck.class 文件。你可以通过运行 ls 命令来验证。

最后,使用 java 命令运行编译后的 Java 程序:

java DuplicateCheck

你应该会看到类似以下的输出:

Original List: [Alice, Bob, Alice, Charlie, Bob]
Duplicates found: [Alice, Bob]

Duplicates found 输出中的元素顺序可能会有所不同,因为 HashSet 不维护插入顺序。

你已经成功使用 HashSet 识别了列表中的重复元素!

比较集合和 Set 的大小

在上一步中,我们使用 HashSet 来查找重复元素。Set 的一个关键特性是它只存储唯一元素。这意味着,如果你向 Set 中添加重复元素,每个元素只会保留一个实例。这个特性在从列表中去除重复元素等任务中非常有用。

在这一步中,我们将修改 DuplicateCheck.java 程序,通过比较原始列表(可能包含重复元素)的大小和从该列表创建的 HashSet(只包含唯一元素)的大小,来展示这个特性。

在 WebIDE 代码编辑器中打开 DuplicateCheck.java 文件。

main 方法修改为如下所示:

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class DuplicateCheck {

    public static void main(String[] args) {
        // Create a list with some duplicate elements
        List<String> names = new ArrayList<>();
        names.add("Alice");
        names.add("Bob");
        names.add("Alice"); // Duplicate
        names.add("Charlie");
        names.add("Bob"); // Duplicate
        names.add("David");

        System.out.println("Original List: " + names);
        System.out.println("Size of Original List: " + names.size());

        // Create a HashSet from the list
        Set<String> uniqueNamesSet = new HashSet<>(names);

        System.out.println("Set created from List: " + uniqueNamesSet);
        System.out.println("Size of Set: " + uniqueNamesSet.size());

        // The difference in size tells us how many duplicates were removed
        int duplicatesCount = names.size() - uniqueNamesSet.size();
        System.out.println("Number of duplicates (excluding first occurrence): " + duplicatesCount);
    }
}

以下是我们添加或修改的内容:

  • 我们向 names 列表中添加了另一个名字 "David",使列表稍微大一些。
  • System.out.println("Size of Original List: " + names.size());:我们使用 size() 方法打印原始列表的大小。
  • Set<String> uniqueNamesSet = new HashSet<>(names);:这是一种直接从另一个 Collection(如我们的 ArrayList)创建 HashSet 的便捷方法。这样做时,HashSet 会自动添加列表中的所有元素,并且由于它是 Set,会丢弃任何重复元素。
  • System.out.println("Size of Set: " + uniqueNamesSet.size());:我们打印 HashSet 的大小。这个大小代表唯一元素的数量。
  • int duplicatesCount = names.size() - uniqueNamesSet.size();:我们计算列表大小和集合大小之间的差值。这个差值告诉我们有多少元素是重复的(不包括它们的首次出现)。

保存修改后的 DuplicateCheck.java 文件。

现在,在终端中再次编译程序:

javac DuplicateCheck.java

如果编译成功,运行程序:

java DuplicateCheck

你应该会看到类似以下的输出:

Original List: [Alice, Bob, Alice, Charlie, Bob, David]
Size of Original List: 6
Set created from List: [Alice, Bob, Charlie, David]
Size of Set: 4
Number of duplicates (excluding first occurrence): 2

注意,原始列表的大小是 6,但从中创建的 HashSet 的大小是 4。差值(6 - 4 = 2)正确地表明有两个重复的名字("Alice" 和 "Bob" 在首次出现后各又出现了一次)。

这展示了你可以多么轻松地使用 HashSet 来找出集合中唯一元素的数量或重复元素的数量。

测试空元素

在前面的步骤中,我们已经了解了 HashSet 如何处理非空的重复元素。现在,让我们来探究一下当尝试向 HashSet 中添加 null 元素时,它会有怎样的表现。了解集合如何处理 null 非常重要,因为如果处理不当,有时可能会导致意外的行为或错误。

HashSet 允许存在一个 null 元素。如果你多次尝试添加 null,只会存储第一个 null

让我们再次修改 DuplicateCheck.java 程序来测试这一点。

在 WebIDE 代码编辑器中打开 DuplicateCheck.java 文件。

修改 main 方法,在列表中包含 null 值:

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class DuplicateCheck {

    public static void main(String[] args) {
        // Create a list with some duplicate and null elements
        List<String> names = new ArrayList<>();
        names.add("Alice");
        names.add("Bob");
        names.add(null); // Add null
        names.add("Alice"); // Duplicate
        names.add("Charlie");
        names.add(null); // Add null again
        names.add("Bob"); // Duplicate
        names.add("David");
        names.add(null); // Add null a third time

        System.out.println("Original List: " + names);
        System.out.println("Size of Original List: " + names.size());

        // Create a HashSet from the list
        Set<String> uniqueNamesSet = new HashSet<>(names);

        System.out.println("Set created from List: " + uniqueNamesSet);
        System.out.println("Size of Set: " + uniqueNamesSet.size());

        // The difference in size tells us how many duplicates were removed
        // Note: This calculation is less straightforward with nulls and duplicates combined
        // int duplicatesCount = names.size() - uniqueNamesSet.size();
        // System.out.println("Number of duplicates (excluding first occurrence): " + duplicatesCount);
    }
}

在这里,我们多次向 names 列表中添加了 null。我们还注释掉了重复元素计数的计算,因为当涉及 null 时,这个计算就变得不那么有意义了,而且我们主要关注的是集合对 null 的处理行为。

保存修改后的 DuplicateCheck.java 文件。

在终端中编译程序:

javac DuplicateCheck.java

如果编译成功,运行程序:

java DuplicateCheck

你应该会看到类似以下的输出:

Original List: [Alice, Bob, null, Alice, Charlie, null, Bob, David, null]
Size of Original List: 9
Set created from List: [null, Alice, Bob, Charlie, David]
Size of Set: 5

观察输出:

  • Original List 显示了所有元素,包括多个 null 值。它的大小为 9。
  • Set created from List 只包含唯一元素。注意,即使 null 在列表中被多次添加,但在集合中它只出现了一次。集合的大小为 5(Alice、Bob、Charlie、David 和 null)。

这证实了 HashSet 允许存在一个 null 元素,并将后续添加的 null 视为重复元素,就像处理其他元素一样。

你现在已经成功测试了 HashSet 如何处理 null 元素。至此,我们对使用 HashSet 进行重复元素检查以及了解其对唯一元素和 null 元素的处理行为的探索就结束了。

总结

在本次实验中,我们学习了如何使用 HashSet 高效地检查 Java 集合中的重复元素。我们创建了一个包含重复元素的 List,然后遍历该列表,尝试将每个元素添加到 HashSet 中。通过检查 add() 方法的返回值(如果元素已存在则返回 false),我们能够识别出重复元素并将它们收集到另一个 HashSet 中。这种方法利用了 HashSet 的唯一元素特性和快速查找能力,从而实现了有效的重复元素检测。