contains()用于判断元素是否在Collection中,依赖equals()比较;自定义类须重写equals()和hashCode();ArrayList为O(n),HashSet平均O(1),TreeSet为O(log n);数组需转集合或遍历;Map用containsKey()/containsValue(),后者性能差;ConcurrentHashMap的containsValue()无强一致性保证。

用 contains() 判断元素是否在 Collection 中
绝大多数 Java 集合(ArrayList、LinkedList、HashSet、TreeSet 等)都继承自 Collection 接口,因此直接支持 contains() 方法。它内部调用元素的 equals() 方法比较,而非 ==。
常见错误:对自定义类未重写 equals()(和 hashCode(),尤其在 HashSet 中),导致 contains() 始终返回 false,即使内容相同。
-
ArrayList的contains()是 O(n) 时间复杂度,逐个遍历比较 -
HashSet的contains()平均是 O(1),但依赖正确实现的hashCode() -
TreeSet的contains()是 O(log n),要求元素可比较(实现Comparable或传入Comparator)
数组不能直接用 contains(),得转成集合或手动遍历
Java 数组不是 Collection,没有 contains() 方法。常见误写 myArray.contains(x) 会编译报错。
安全做法取决于场景:
立即学习“Java免费学习笔记(深入)”;
- 小数组、一次性判断:用
Arrays.asList(arr).contains(x)—— 注意基本类型数组(如int[])会装箱为Integer[],且asList()返回的是固定大小列表,不支持增删 - 频繁查找或大数组:先转
HashSet缓存(new HashSet(Arrays.asList(arr))),再查contains() - 原始类型数组(
int[]、double[]):只能用循环或IntStream.of(arr).anyMatch(i -> i == x)
Map 查键用 containsKey(),查值用 containsValue()
Map 不是 Collection,它的 contains() 方法不存在。误调用会编译失败。
区分清楚语义:
- 查“键是否存在”:用
map.containsKey(key),时间复杂度通常 O(1)(HashMap)或 O(log n)(TreeMap) - 查“值是否存在”:用
map.containsValue(value),这是 O(n) 全遍历操作,性能差,慎用 - 如果需要高效查值,考虑反向建一个
Map,或额外维护一个Set
并发集合如 ConcurrentHashMap 的查找行为
ConcurrentHashMap 的 containsKey() 和 get() 是线程安全的,但 containsValue() 仍是 O(n) 且可能返回过期结果(因遍历时其他线程可能修改)。
特别注意:
-
ConcurrentHashMap没有contains()方法,也不支持containsValue()的强一致性保证 - 若业务逻辑依赖“值一定存在”,不要依赖
containsValue()的返回结果做后续操作,改用get()+ 判空更可靠 - 高并发下查值需求频繁时,应从数据结构设计层面规避,比如把要查的值也作为 key 存一份
equals()/hashCode() 实现完整性,以及对基本类型数组的误用——这两处出问题,调试时往往卡很久。









