Java 当映射明显包含HashMap键时,HashMap键返回null
我目前正试图解决一个代号战问题,题为“战舰:沉没受损或未被触碰?”?。给定一个包含“舰船”的2D数组和另一个包含攻击坐标的2D数组,我必须生成一个分数。我用船的位置填充一个hashmap,然后对照地图检查攻击位置。打印时,第一个测试用例上的原始位置和攻击是相同的。尽管如此,Java 当映射明显包含HashMap键时,HashMap键返回null,java,null,hashmap,Java,Null,Hashmap,我目前正试图解决一个代号战问题,题为“战舰:沉没受损或未被触碰?”?。给定一个包含“舰船”的2D数组和另一个包含攻击坐标的2D数组,我必须生成一个分数。我用船的位置填充一个hashmap,然后对照地图检查攻击位置。打印时,第一个测试用例上的原始位置和攻击是相同的。尽管如此,map.get() 公共级战舰ssdn{ 公共静态地图损坏(最终int[][]板,最终int[][]攻击){ int-y; HashMap ships=newhashmap(); //绘制船只位置图 对于(int i=0;i0
map.get()
公共级战舰ssdn{
公共静态地图损坏(最终int[][]板,最终int[][]攻击){
int-y;
HashMap ships=newhashmap();
//绘制船只位置图
对于(int i=0;i0){
如果(leftShip1==0)沉没++;
如果(ship1%leftShip1>0)点击++;
如果(ship1==leftShip1)遗漏了++;
}
如果(ship2>0){
如果(leftShip2==0)沉没++;
如果(ship2%leftShip2>0)点击++;
如果(ship2==leftShip2)遗漏了++;
}
如果(ship3>0){
如果(leftShip3==0)沉没++;
如果(ship3%leftShip3>0)点击++;
如果(ship3==leftShip3)遗漏了++;
}
HashMap分数=新HashMap();
得分。放(“下沉”,下沉);
得分。放置(“损坏”,命中);
得分。推杆(“未触球”,未命中);
得分。推杆(“得分”,下沉+命中/2-未命中);
返回分数;
}
}
我不是要你帮我解决这个问题。我完全不明白为什么我的HashMap会这样。这可能意味着这是一件很小很愚蠢的事情
注意:位置的y值被翻转,因为在问题“板”中,y坐标是从底部测量的。因此,在4x4电路板或阵列中,索引[0][0]对应于坐标(1,4)
问题是您正在使用int[]
作为HashMap
的键。数组不重写方法equals
和hashCode
。因此,对于他们来说,这些方法通过对象的身份来比较对象,而不是通过对象的内容来比较对象
考虑这一点:
int[] first = new int[] { 1, 2, 3 };
int[] second = new int[] { 1, 2, 3 };
System.out.println(first.equals(second)); // Prints 'false'
两个数组的内容相同,但它们被视为不相等,因为它们是不同的对象(第一个!=第二个
)
当您现在调用类似于map.get(key)
的函数时,map使用其散列码搜索键,该散列码是由散列码
方法返回的。但是,此方法也适用于阵列的标识库
如果您现在使用密钥存储数据,然后重新创建具有相同内容的密钥,以便获取数据,您将无法再找到它:
Map<int[], String> map = new HashMap<>();
// Put data
int[] key = new int[] { 1, 2, 3 };
map.put(key, "test");
// Retrieve it
int[] similarKey = new int[] { 1, 2, 3 };
String data = map.get(similarKey); // Is 'null', not ' test'
// Try it with 'key' instead of 'similarKey'
String otherData = map.get(key); // Works now since same object
int[]s
不要覆盖等于和哈希码
;它们通过标识进行比较。通常用于数组。在映射中作为键的数组不起作用。尝试另一种数据结构。出于对
的热爱,请优先使用集合而不是数组。如果您改为使用List
而不是int[]
您的问题将消失。实际上,最好将变量定义为其最抽象的类型,即List
而不是ArrayList
。看,这是正确的。为了简单起见,我避免了这种情况。但是,如果您想用列表
替换int[]
,最好强制执行ArrayList
,这样每个人都知道基于索引的访问工作得很快,但这只是OP的一个旁注。感谢您抽出时间为我回答这个问题。在意识到使用对象作为散列键的问题后,肯定会有重复的问题,像这样的问题。@dillashmog,欢迎光临。这很好,特别是如果你不知道问题出在哪里。我的意思是,你应该如何寻找你不知道的东西。
Map<int[], String> map = new HashMap<>();
// Put data
int[] key = new int[] { 1, 2, 3 };
map.put(key, "test");
// Retrieve it
int[] similarKey = new int[] { 1, 2, 3 };
String data = map.get(similarKey); // Is 'null', not ' test'
// Try it with 'key' instead of 'similarKey'
String otherData = map.get(key); // Works now since same object
Map<List<Integer>, String> map = new HashMap<>();
// Put data
int[] key = new int[] { 1, 2, 3 };
List<Integer> keyAsList = new ArrayList<>(Arrays.asList(key));
map.put(keyAsList, "test");
// Retrieve it
int[] similarKey = new int[] { 1, 2, 3 };
List<Integer> similarKeyAsList = new ArrayList<>(Arrays.asList(similarKey));
String data = map.get(similarKeyAsList); // Is 'test' now