Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 当映射明显包含HashMap键时,HashMap键返回null_Java_Null_Hashmap - Fatal编程技术网

Java 当映射明显包含HashMap键时,HashMap键返回null

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

我目前正试图解决一个代号战问题,题为“战舰:沉没受损或未被触碰?”?。给定一个包含“舰船”的2D数组和另一个包含攻击坐标的2D数组,我必须生成一个分数。我用船的位置填充一个hashmap,然后对照地图检查攻击位置。打印时,第一个测试用例上的原始位置和攻击是相同的。尽管如此,
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