如何判断HashMap中是否存在值匹配的List类型Key
根因说明
你遇到的问题有两层原因:
- 你调用
Arrays.asList()传入基本类型int[]时,方法不会自动拆箱,只会把整个int数组作为单个元素存入List,你得到的实际是List<int[]>类型,而非你预期存储int值的List<Integer>。 - 此时List中存储的是int数组对象,数组的
equals方法默认对比内存地址而非元素值,所以两个内容相同的不同int数组会被判定为不相等,导致查询返回null。
解决方案
JDK中所有实现了List接口的集合类(比如ArrayList),默认的equals和hashCode方法已经实现了按顺序匹配内部元素值的逻辑,你只需要正确构造元素为包装类型Integer的List作为Key即可,下面是两种常用实现方案:
方案1:直接将int数组转为
List<Integer>作为Key
代码示例:
插入键值对:int[] arr = { 1, 2, 3, 4, 5 }; // 将int数组转为元素为Integer的List List<Integer> key = Arrays.stream(arr).boxed().toList(); my_map.put(key, "12345");查询键值对:
int[] test_arr = { 1, 2, 3, 4, 5 }; List<Integer> testKey = Arrays.stream(test_arr).boxed().toList(); if (my_map.get(testKey) != null) { // 逻辑可以正常执行 }方案2:封装自定义Key类(适合需要规避Key被修改的场景)
如果担心后续误修改List中的元素导致HashMap索引失效,可以自定义不可变的Key类,直接基于int数组的元素值计算相等性和哈希值:import java.util.Arrays; public final class IntArrayKey { private final int[] arr; public IntArrayKey(int[] inputArr) { // 做防御性拷贝,避免外部修改数组影响Key的取值 this.arr = inputArr.clone(); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; IntArrayKey that = (IntArrayKey) o; // 对比数组元素值而非地址 return Arrays.equals(arr, that.arr); } @Override public int hashCode() { // 基于数组元素值计算哈希 return Arrays.hashCode(arr); } }使用方式:
// 插入 my_map.put(new IntArrayKey(arr), "12345"); // 查询 my_map.get(new IntArrayKey(test_arr)); // 可正常匹配到值
注意:不要使用可变对象作为HashMap的Key,如果你把List作为Key存入HashMap后修改了List内的元素,会导致Key的哈希值变化,后续无法正常查询到对应键值对。
内容的提问来源于stack exchange,提问作者Eran Gabriel
相关产品推荐
相关产品推荐

