1. 简介

在本篇教程中,我们将探讨如何判断一个 List 中的所有元素是否都相同。

同时,我们也会分析每种方案的时间复杂度(Big O 表示法),以便了解其在最坏情况下的性能表现。

2. 示例数据

假设我们有以下三个列表:

notAllEqualList = Arrays.asList("Jack", "James", "Sam", "James");
emptyList = Arrays.asList();
allEqualList = Arrays.asList("Jack", "Jack", "Jack", "Jack");

我们的目标是设计几种解决方案,使得只有对 emptyListallEqualList 返回 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()

StreamallMatch() 方法非常适合用来检测所有元素是否满足某个条件:

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)*,但在实际应用中,你可以根据项目环境、团队习惯以及具体需求选择最适合的一种。


原始标题:Determine If All Elements Are the Same in a Java List | Baeldung