1. 简介
在本篇教程中,我们将探讨如何判断一个 List
中的所有元素是否都相同。
同时,我们也会分析每种方案的时间复杂度(Big O 表示法),以便了解其在最坏情况下的性能表现。
2. 示例数据
假设我们有以下三个列表:
notAllEqualList = Arrays.asList("Jack", "James", "Sam", "James");
emptyList = Arrays.asList();
allEqualList = Arrays.asList("Jack", "Jack", "Jack", "Jack");
我们的目标是设计几种解决方案,使得只有对 emptyList
和 allEqualList
返回 true
。
3. 基础遍历法
很显然,如果所有元素都相等,那么它们都应该等于第一个元素。我们可以利用这一点来进行循环判断:
public boolean verifyAllEqualUsingALoop(List<String> list) {
for (String s : list) {
if (!s.equals(list.get(0)))
return false;
}
return true;
}
✅ 优点:时间复杂度为 *O(n)*,但通常可以在中途提前退出,提升效率。
4. 使用 HashSet
我们也可以借助 HashSet
来实现,因为 HashSet
中不允许重复元素。如果我们把一个 List
转换成 HashSet
后,其大小小于等于 1,就说明原列表中所有元素都相同。
public boolean verifyAllEqualUsingHashSet(List<String> list) {
return new HashSet<String>(list).size() <= 1;
}
⚠️ 注意:
- 将
List
转换为HashSet
的时间复杂度是 *O(n)*; - 调用
size()
方法的时间复杂度是 *O(1)*; - 因此整体时间复杂度仍是 *O(n)*;
5. 使用 Collections API
另一种方式是使用 Collections 类中的 frequency(Collection c, Object o)
方法。该方法会返回集合 c
中与对象 o
相等的元素个数。
所以,如果我们发现频率等于列表长度,就说明所有元素都相等:
public boolean verifyAllEqualUsingFrequency(List<String> list) {
return list.isEmpty() || Collections.frequency(list, list.get(0)) == list.size();
}
📌 时间复杂度依然是 *O(n)*,因为 Collections.frequency()
内部也是通过基本循环实现的。
6. 使用 Stream API
Java 8 引入了强大的 Stream
API,它也提供了多种判断列表元素是否全部相等的方法。
6.1. 利用 distinct()
可以使用 distinct()
方法对流去重后统计数量:
public boolean verifyAllEqualUsingStream(List<String> list) {
return list.stream()
.distinct()
.count() <= 1;
}
✅ 如果去重后的元素数量 ≤ 1,则说明所有元素都一样。
⏰ 时间复杂度:O(n) —— 需要遍历整个流。
6.2. 利用 allMatch()
Stream
的 allMatch()
方法非常适合用来检测所有元素是否满足某个条件:
public boolean verifyAllEqualAnotherUsingStream(List<String> list) {
return list.isEmpty() || list.stream()
.allMatch(list.get(0)::equals);
}
⏰ 时间复杂度同样是 *O(n)*。
7. 第三方库支持
如果你还在使用较老版本的 Java,无法使用 Stream API,可以考虑使用第三方库,比如 Google Guava 或 Apache Commons。
这些方案本质上都是一样的思路:遍历列表并和第一个元素比较,因此时间复杂度同样是 *O(n)*。
7.1. Maven 依赖配置
你可以根据需要添加如下依赖:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
</dependency>
或者:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.4</version>
</dependency>
7.2. Google Guava 实现
Guava 提供了 Iterables.all()
方法,可以判断所有元素是否符合某个谓词:
public boolean verifyAllEqualUsingGuava(List<String> list) {
return Iterables.all(list, new Predicate<String>() {
public boolean apply(String s) {
return s.equals(list.get(0));
}
});
}
7.3. Apache Commons 实现
Apache Commons 提供了 IterableUtils.matchesAll()
方法,作用类似:
public boolean verifyAllEqualUsingApacheCommon(List<String> list) {
return IterableUtils.matchesAll(list, new org.apache.commons.collections4.Predicate<String>() {
public boolean evaluate(String s) {
return s.equals(list.get(0));
}
});
}
8. 总结
本文介绍了多种判断 Java List
中所有元素是否相等的方式:
- ✅ 基础循环:简单粗暴,适合快速上手;
- ✅ HashSet:代码简洁,逻辑清晰;
- ✅ Collections.frequency:标准库方案,无需额外依赖;
- ✅ Stream API:现代写法,函数式风格;
- ✅ 第三方库:兼容旧版 Java,功能丰富;
虽然所有方案的时间复杂度都是 *O(n)*,但在实际应用中,你可以根据项目环境、团队习惯以及具体需求选择最适合的一种。