LinkedHashMap中的NullPointerException

Zyg*_*tas -10 java nullpointerexception linkedhashmap

我在创造一个游戏.当我正在阅读LinkedHashMap时,它给了我一个NPE.

我这样填写LinkedHashMap hm:

for (String s : line.split("")) {
    if (s.contains("*")) {
        hm.put(new Coordinates(xa-32, ya), "gray");
    } else if (s.contains("#")) {
        hm.put(new Coordinates(xa-32, ya), "black");
    }
    // other code...
}
Run Code Online (Sandbox Code Playgroud)

后来我尝试从这样的HashMap中获取颜色,并得到一个NPE:

if ((keyCode == KeyEvent.VK_LEFT || keyCode == KeyEvent.VK_A)
    && isPainted && hm.get(new Coordinates(x - 32, y)).equalsIgnoreCase("gray")) {
    x -= 32;
}
Run Code Online (Sandbox Code Playgroud)

完整代码:

lib*_*bik 10

在此行中hm.get(new Coordinates(x, y - 32)).equalsIgnoreCase("gray")),不可能hm包含新创建的坐标.

例如Coordinates c = new Coordinates(x, y - 32);,在创建新对象时,在内存中创建该对象,该变量c保存对该内存的引用,而不是对象本身.

因此,看看这段代码:

Coordinates c1 = new Coordinates(x, y - 32); //c1 holds reference to memory, something like "a8wgge8h"
Coordinates c2 = new Coordinates(x, y - 32); //c2 holds also reference to memory, someting like "a8w12238h"
if (c1 != c2){
   System.out.println("Yes, it is true, c1 is not c2, there are two objects with same properties, but they are not same, like human twins - they look same, but two people actually exists");
}
Run Code Online (Sandbox Code Playgroud)

因此,您无法找到任何内容hm.get(new Coordinates(x, y - 32)),因为它不会查找具有相同x,y内容的坐标,它会查找与内存相同的坐标.并且它不存在,因为你只是创建新对象,java将它与新的内存地址相关联abnbn147,然后你的list/set查找带有地址的对象abnbn147,这些对象无法存储在那里,因为你刚刚创建了它.

hm.get(new Coordinates(x, y - 32))总是返回null.如果你在null上调用方法,它会以NullPointerException结束,这equalsIgnoreCase是在我讨论的null对象上调用方法时发生的.


big*_*Guy 5

为了使它工作,在类Coordinates中实现equals和hashCode方法.

例:

@Override
public int hashCode()
{
  return 10000*x+y;
}

@Override
public boolean equals(Object obj)
{
  if(obj == null)
    return false;
  if (getClass() != obj.getClass())
    return false;
  Coordinates other = (Coordinates)obj;
  return x == other.getX() && y == other.getY();
}
Run Code Online (Sandbox Code Playgroud)

更长的解释:

LinkedHashMap使用equals方法将您的密钥与map中已有的密钥进行比较.默认的equals方法比较对象引用,所以如果你有

Coordinates a = new Coordinates(1, 1); 
Coordinates b = new Coordinates(1, 1);
Run Code Online (Sandbox Code Playgroud)

a.equals(b)返回false.如果不覆盖equals方法,则hashmap将找不到包含密钥的项.

如果重写equals()方法,则必须实现hashCode().每当a.equals(b),则a.hashCode()必须与b.hashCode()相同.

http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals(java.lang.Object) http://docs.oracle.com/javase/7/docs/ API /爪哇/郎/ Object.html#hashCode()方法