ArrayList 查找元素主要靠 contains() 方法和手动遍历,依赖正确重写的 equals();contains() 时间复杂度 O(n),indexOf()/lastIndexOf() 可获取位置;自定义查找推荐增强 for 或 Stream;注意重写 equals/hashCode、避免 == 比较、线程不安全及高频查找可转 HashSet。

ArrayList 在 Java 中查找和判断是否包含某个元素,主要靠 contains() 方法和手动遍历(如 indexOf()、lastIndexOf() 或增强 for 循环 + 条件判断)来实现。核心前提是:元素的 equals() 方法必须正确重写,否则可能查不到。
用 contains() 快速判断是否存在
contains(Object o) 是最常用的方式,内部调用 indexOf(o) != -1,本质是顺序遍历并调用 equals() 比较:
- 返回
true表示至少有一个元素与目标相等(基于equals()) - 对
null值也安全:如果传入null,会检查列表中是否有null元素 - 时间复杂度为 O(n),不推荐在大列表中高频调用
示例:
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c")); boolean hasB = list.contains("b"); // true boolean hasX = list.contains("x"); // false获取元素位置:indexOf() 和 lastIndexOf()
如果不仅要判断存在,还要知道“在哪”,就用这两个方法:
立即学习“Java免费学习笔记(深入)”;
-
indexOf(Object o)返回第一次出现的索引,没找到返回-1 -
lastIndexOf(Object o)返回最后一次出现的索引,同样没找到返回-1 - 它们也依赖
equals(),不是==
示例:
List<Integer> nums = Arrays.asList(1, 2, 3, 2, 4); int first2 = nums.indexOf(2); // 1 int last2 = nums.lastIndexOf(2); // 3自定义查找逻辑(比如找满足条件的对象)
当需要按属性、范围或复合条件查找时,contains() 不够用,得手动遍历:
- 用增强 for 循环 + if 判断,适合简单逻辑
- JDK 8+ 推荐用
stream().anyMatch()判断是否存在,stream().filter().findFirst()获取匹配项 - 注意:流操作不会修改原列表,但有轻微开销;循环更直观、轻量
示例(查找 name 为 "Alice" 的 Person):
List<Person> people = ...; // 方式1:传统循环 Person found = null; for (Person p : people) { if ("Alice".equals(p.getName())) { found = p; break; } } // 方式2:Stream(JDK 8+) Optional<Person> opt = people.stream() .filter(p -> "Alice".equals(p.getName())) .findFirst(); Person result = opt.orElse(null);注意事项和常见坑
实际使用中容易忽略的关键点:
- 自定义类必须重写
equals()(通常也要重写hashCode()),否则contains()总返回false - 不要用
==判断内容相等,字符串要用.equals(),基本类型包装类建议用.equals()或直接用Objects.equals(a, b) - ArrayList 不是线程安全的,多线程环境下并发查找+修改需加锁或改用
Collections.synchronizedList() - 若查找非常频繁且数据稳定,可考虑转成
HashSet提升到 O(1),但会丢失顺序和重复元素


















