1. 概述
在Java中处理数组时,我们经常需要验证数组中的所有元素是否相等。
本文将探讨在Java中检查数组所有元素是否相等的多种实现方案。
2. 问题引入
检查数组元素是否相等看似简单,但需要考虑一些边界情况:
- 数组为
null
或空数组 - 仅包含单个元素的数组
- 包含
null
值的数组
此外,Java中存在对象数组和基本类型数组两种类型。本文将覆盖这些场景。
首先看对象数组的处理方案。
3. 对象数组
先定义几个测试用例数组:
// 所有元素相等的数组:
final static String[] ARRAY_ALL_EQ = { "java", "java", "java", "java" };
final static String[] ARRAY_ALL_NULL = { null, null, null, null };
final static String[] ARRAY_SINGLE_EL = { "java" };
// 所有元素不相等的数组:
final static String[] ARRAY_NOT_EQ = { "java", "kotlin", "java", "java" };
final static String[] ARRAY_EMPTY = {};
final static String[] ARRAY_NULL = null;
注意:✅ 单元素数组视为所有元素相等
❌ null
或空数组视为元素不相等(因为根本没有元素)
3.1. 基于循环的泛型方法
最直接的方法是遍历数组逐个比较。使用泛型实现通用方案:
<T> boolean isAllEqual(T[] array) {
if (array == null || array.length == 0) {
return false;
}
for (int i = 1; i < array.length; i++) {
if (!Objects.equals(array[0], array[i])) {
return false;
}
}
return true;
}
关键点:
- 先处理
null
和空数组边界情况 - 将每个元素与首元素
array[0]
比较 - 使用
Objects.equals()
而非equals()
——避免NPE的坑!
测试验证:
assertTrue(isAllEqual(ARRAY_ALL_EQ));
assertTrue(isAllEqual(ARRAY_ALL_NULL));
assertTrue(isAllEqual(ARRAY_SINGLE_EL));
assertFalse(isAllEqual(ARRAY_NOT_EQ));
assertFalse(isAllEqual(ARRAY_EMPTY));
assertFalse(isAllEqual(ARRAY_NULL));
3.2. 使用Stream的distinct()或allMatch()
Java 8的Stream API提供了更简洁的方案:
方案1:distinct()去重
<T> boolean isAllEqualByDistinct(T[] array) {
// ... null和空数组处理
return Arrays.stream(array)
.distinct()
.count() == 1;
}
原理:所有元素相等时,去重后只剩1个元素
方案2:allMatch()全匹配
<T> boolean isAllEqualByAllMatch(T[] array) {
// ... null和空数组处理
return Arrays.stream(array)
.allMatch(element -> Objects.equals(array[0], element));
}
原理:检查所有元素是否都与首元素匹配
两种方案测试结果一致:
assertTrue(isAllEqualByDistinct(ARRAY_ALL_EQ));
assertTrue(isAllEqualByDistinct(ARRAY_ALL_NULL));
assertTrue(isAllEqualByDistinct(ARRAY_SINGLE_EL));
assertFalse(isAllEqualByDistinct(ARRAY_NOT_EQ));
assertFalse(isAllEqualByDistinct(ARRAY_EMPTY));
assertFalse(isAllEqualByDistinct(ARRAY_NULL));
4. 基本类型数组
以int[]
为例,处理基本类型数组:
final static int[] INT_ARRAY_ALL_EQ = { 7, 7, 7, 7 };
final static int[] INT_ARRAY_SINGLE_EL = { 42 };
final static int[] INT_ARRAY_NOT_EQ = { 7, 7, 7, 42 };
⚠️ 注意:基本类型数组没有null
元素,无需处理ARRAY_ALL_NULL
情况
4.1. 循环方案
boolean isAllEqual(int[] array) {
// ... null和空数组处理
for (int i = 1; i < array.length; i++) {
if (array[0] != array[i]) {
return false;
}
}
return true;
}
关键点:
- 必须用
==
比较基本类型(不能用equals()
) - 避免使用
Objects.equals()
防止自动装箱(性能优化)
测试验证:
assertTrue(isAllEqual(INT_ARRAY_ALL_EQ));
assertTrue(isAllEqual(INT_ARRAY_SINGLE_EL));
assertFalse(isAllEqual(INT_ARRAY_NOT_EQ));
4.2. 使用Stream的distinct()或allMatch()
利用基本类型Stream(如IntStream
):
// distinct()方案
boolean isAllEqualByDistinct(int[] array) {
// ... null和空数组处理
return IntStream.of(array)
.distinct()
.count() == 1;
}
// allMatch()方案
boolean isAllEqualByAllMatch(int[] array) {
// ... null和空数组处理
return IntStream.of(array)
.allMatch(element -> array[0] == element);
}
测试结果:
assertTrue(isAllEqualByDistinct(INT_ARRAY_ALL_EQ));
assertTrue(isAllEqualByDistinct(INT_ARRAY_SINGLE_EL));
assertFalse(isAllEqualByDistinct(INT_ARRAY_NOT_EQ));
5. 总结
本文探讨了检查数组元素是否相等的多种方案:
- ✅ 对象数组:循环/Stream(
distinct()
/allMatch()
) - ✅ 基本类型数组:循环/基本类型Stream
关键注意事项:
- 边界情况处理(
null
/空数组) - 基本类型用
==
,对象类型用Objects.equals()
- Stream方案更简洁,循环方案性能更优
完整代码示例见GitHub仓库。