简介
在这个实验中,你将学习如何高效地检查 Java 集合中是否存在重复元素。我们将探索使用 HashSet
(Java 集合框架中的一个强大工具)来识别重复元素。
通过实际操作步骤,你将首先学习如何利用 HashSet
的元素唯一性特性来检测重复元素。然后,你将发现另一种方法,即比较原始集合和由其创建的 HashSet
的大小。最后,我们将探讨在检查重复元素时如何处理空元素。
在这个实验中,你将学习如何高效地检查 Java 集合中是否存在重复元素。我们将探索使用 HashSet
(Java 集合框架中的一个强大工具)来识别重复元素。
通过实际操作步骤,你将首先学习如何利用 HashSet
的元素唯一性特性来检测重复元素。然后,你将发现另一种方法,即比较原始集合和由其创建的 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<>();
:这行代码创建了一个名为 names
的 List
,它可以存储 String
对象。我们使用 ArrayList
作为 List
接口的具体实现。names.add(...)
:这行代码向我们的 names
列表中添加元素。注意,"Alice" 和 "Bob" 被添加了两次。Set<String> uniqueNames = new HashSet<>();
:这行代码使用 HashSet
实现创建了一个名为 uniqueNames
的 Set
。Set
保证只包含唯一元素。Set<String> duplicates = new HashSet<>();
:这行代码创建了另一个 Set
,用于存储我们找到的重复元素。for (String name : names)
:这是一个 for-each
循环,用于遍历 names
列表中的每个 name
。if (!uniqueNames.add(name))
:HashSet
的 add()
方法在元素成功添加(即该元素不在集合中)时返回 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
识别了列表中的重复元素!
在上一步中,我们使用 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
的唯一元素特性和快速查找能力,从而实现了有效的重复元素检测。