总结概览
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 循环遍历 | 最基础,无需任何额外知识或库 | 代码冗长,效率相对较低 | 学习基础,面试考点,简单脚本 |
Arrays.binarySearch() |
效率极高 (O(log n)) | 前提:数组必须已排序,否则结果错误 | 已排序的大型数组,追求极致性能 |
Arrays.asList().contains() |
代码简洁,可读性好 | 有性能开销 (O(n)),会创建一个新列表对象 | 中小型数组,代码简洁性优先于性能 |
| Java 8 Stream API | 现代、函数式,代码简洁,可链式调用 | 有性能开销 (O(n)),对于简单场景可能略显复杂 | 现代Java项目,需要与其他流操作结合时 |
| Apache Commons Lang | 代码最简洁,经过高度优化 | 需要引入第三方库 | 已在项目中使用该库,或追求极致的代码简洁 |
方法1:使用 for 循环(最基础)
这是最原始、最直接的方法,不依赖任何 Java 库,适合初学者理解底层逻辑。

原理:手动遍历数组中的每一个元素,如果找到与目标值相等的元素,就立即返回 true,如果遍历完整个数组都没有找到,就返回 false。
import java.util.Arrays;
public class ArrayContainsExample {
public static boolean containsUsingLoop(int[] array, int valueToFind) {
// 处理 null 数组的情况
if (array == null) {
return false;
}
// 遍历数组
for (int element : array) {
if (element == valueToFind) {
return true; // 找到即返回
}
}
return false; // 循环结束未找到
}
public static void main(String[] args) {
int[] numbers = {1, 2, 3, 4, 5};
int target = 3;
if (containsUsingLoop(numbers, target)) {
System.out.println("数组中包含 " + target);
} else {
System.out.println("数组中不包含 " + target);
}
// 测试不包含的情况
int notFound = 6;
if (!containsUsingLoop(numbers, notFound)) {
System.out.println("数组中不包含 " + notFound);
}
}
}
- 优点:直观,无任何依赖。
- 缺点:代码量多,不如其他方法简洁。
方法2:使用 Arrays.binarySearch()(最高效,但有前提)
如果你确定数组是有序的(从小到大或从大到小),这是最快的方法。
原理:使用二分查找算法,其时间复杂度为 O(log n),远快于线性查找的 O(n)。
⚠️ 重要:如果数组未排序,binarySearch 的行为是未定义的,它可能返回错误的结果,比如返回一个负数表示“未找到”,但这不代表该值真的不在数组中。

import java.util.Arrays;
public class BinarySearchExample {
public static void main(String[] args) {
// 数组必须是有序的!
int[] sortedNumbers = {1, 3, 5, 7, 9};
int target = 5;
// 使用 binarySearch
// 如果找到,返回元素的索引(>= 0)
// 如果未找到,返回 (-(插入点) - 1)(一个负数)
int result = Arrays.binarySearch(sortedNumbers, target);
if (result >= 0) {
System.out.println("数组中包含 " + target + ",索引在: " + result);
} else {
System.out.println("数组中不包含 " + target);
}
// 错误示例:对未排序的数组使用 binarySearch
int[] unsortedNumbers = {9, 1, 5, 3, 7};
int wrongResult = Arrays.binarySearch(unsortedNumbers, 5);
System.out.println("对未排序数组查找5的结果是: " + wrongResult); // 可能是 -6 或其他意想不到的值
}
}
- 优点:在数组已排序的情况下,查找速度极快。
- 缺点:仅适用于已排序的数组,如果数组未排序,必须先排序(排序本身是 O(n log n) 的开销),这可能会让该方法失去优势。
方法3:使用 Arrays.asList().contains()(最常用)
这是最简洁、最通用的方法,适用于任何类型的数组(包括基本类型和对象类型)。
原理:Arrays.asList() 将数组转换为一个固定大小的 List 视图,然后调用 List 接口自带的 contains() 方法。
import java.util.Arrays;
public class AsListContainsExample {
public static void main(String[] args) {
// 对基本类型数组
int[] numbers = {1, 2, 3, 4, 5};
int target = 3;
// 注意:Arrays.asList(numbers) 会创建一个包含数组本身作为唯一元素的 List
// List<int[]> 而不是 List<Integer>
// 所以对于基本类型数组,需要先转换为对象数组
boolean contains = Arrays.stream(numbers).boxed().collect(Collectors.toList()).contains(target);
System.out.println("基本类型数组是否包含 " + target + ": " + contains);
// 更好的方式是直接使用 Stream (见方法4)
// 或者,对于对象数组,这个方法非常直接
String[] names = {"Alice", "Bob", "Charlie"};
String nameToFind = "Bob";
// 对于对象数组,直接使用即可
boolean nameContains = Arrays.asList(names).contains(nameToFind);
System.out.println("字符串数组是否包含 " + nameToFind + ": " + nameContains);
}
}
- 优点:代码非常简洁,可读性高,适用于对象数组。
- 缺点:
- 对于基本类型数组(如
int[]),不能直接使用,需要先转换(使用 Stream API 会更方便)。 Arrays.asList()会创建一个新的ArrayList对象(尽管是视图),对于非常大的数组可能会有轻微的性能开销。contains()方法本身仍然是线性查找,时间复杂度为 O(n)。
- 对于基本类型数组(如
方法4:使用 Java 8 Stream API(现代推荐)
这是 Java 8 引入的现代函数式方法,代码优雅且功能强大。
原理:将数组转换为流,然后使用 anyMatch() 方法检查是否存在至少一个元素满足给定的条件。

import java.util.Arrays;
public class StreamContainsExample {
public static void main(String[] args) {
// 对基本类型数组
int[] numbers = {1, 2, 3, 4, 5};
int target = 3;
// 使用 Stream API
boolean containsInt = Arrays.stream(numbers).anyMatch(num -> num == target);
System.out.println("基本类型数组是否包含 " + target + ": " + containsInt);
// 对对象数组
String[] names = {"Alice", "Bob", "Charlie"};
String nameToFind = "Bob";
boolean containsString = Arrays.stream(names).anyMatch(name -> name.equals(nameToFind));
System.out.println("字符串数组是否包含 " + nameToFind + ": " + containsString);
// 可以使用方法引用简化代码
boolean containsStringRef = Arrays.stream(names).anyMatch("Bob"::equals);
System.out.println("使用方法引用是否包含 Bob: " + containsStringRef);
}
}
- 优点:
- 代码简洁、现代。
- 统一地处理基本类型和对象类型的数组。
- 可与 Stream 的其他操作(如
filter,map,collect)无缝链式调用,功能强大。
- 缺点:
- 对于这种简单的“包含”检查,相比传统的 for 循环,可能会有微小的性能开销(但通常可以忽略不计)。
- 需要理解 Java 8 Stream 的基本概念。
方法5:使用 Apache Commons Lang(第三方库)
如果你的项目中已经使用了 Apache Commons Lang 库,这是最简单、最可靠的选择。
原理:ArrayUtils 工具类提供了 contains() 静态方法。
你需要添加依赖 (Maven):
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version> <!-- 使用最新版本 -->
</dependency>
代码示例:
import org.apache.commons.lang3.ArrayUtils;
public class ApacheCommonsExample {
public static void main(String[] args) {
int[] numbers = {1, 2, 3, 4, 5};
int target = 3;
if (ArrayUtils.contains(numbers, target)) {
System.out.println("数组中包含 " + target);
}
String[] names = {"Alice", "Bob", "Charlie"};
String nameToFind = "David";
if (!ArrayUtils.contains(names, nameToFind)) {
System.out.println("数组中不包含 " + nameToFind);
}
}
}
- 优点:代码最简洁,可读性极高,库本身经过高度优化。
- 缺点:需要引入第三方依赖。
如何选择?
- 如果你是初学者或在学习基础:使用 for 循环,理解其原理。
- 如果你的数组是已排序的且性能至关重要:使用
Arrays.binarySearch()。 - 如果你在写简单的代码,且追求简洁(特别是对象数组):使用
Arrays.asList().contains()。 - 如果你在编写现代 Java (8+) 代码:Stream API 是非常好的选择,因为它功能全面且符合现代编程风格。
- 如果你的项目已经依赖了 Apache Commons Lang:直接使用
ArrayUtils.contains(),这是最省事的方式。
