0

I have the following class:

public static final Map<ChunkLoc,String> claims = new HashMap<>();

public final UUID world;
public final int x;
public final int z;

public static void main(String[] aefjpa) throws Throwable {
    final UUID u = UUID.randomUUID();

    final ChunkLoc c = new ChunkLoc(u, 123, -634);
    claims.put(c, "apekop");
    System.out.println(c.getOwner());

    final ChunkLoc a = new ChunkLoc(u, 123, -634);
    System.out.println(a.getOwner());

    System.out.println(a.equals(c));
}

public ChunkLoc(final UUID world, final int x, final int z) {
    this.world = world;
    this.x = x;
    this.z = z;
}

public String getOwner() {
    return claims.get(this);
}

public boolean equals(final ChunkLoc chunk) {
    return world.equals(chunk.world) && x == chunk.x && z == chunk.z;
}

public int hashCode() {
    return x << z;
}

For some reason, the claims Map is not working as expected. When I create a ChunkLoc to put a String in the map and then create another ChunkLoc with the same values to get the String back from the map, it returns null. The main() method outputs the following:

apekop
null
true

I thought a HashMap should be functioning differently when the hashCode is the same and equals() returns true. Why is it giving the above output?

Priv
  • 812
  • 2
  • 9
  • 23
  • You should generally avoid using objects as a key into a Map. Each new instantiation of an object is, by default, considered to be a _different_ object, even if all of its values are identical. If you *must* use an object as a Map's key, that object needs to override the `equals` and `hashcode` methods from `Object`, so that they can be appropriately compared and hashed. – Jordan Feb 03 '20 at 20:42
  • The code I posted above *is* the ChunkLoc class. As you can see, it implements both `equals` and `hashCode`. – Priv Feb 03 '20 at 20:43
  • I have clearly done that in the main() method and as you can see in the output, it returns true. – Priv Feb 03 '20 at 20:44
  • 4
    Ah, okay - your equals method is wrong. It should take `Object`. Add an `@Override` annotation and watch the compiler complain. – Boris the Spider Feb 03 '20 at 20:44
  • Ah, thank you. I normally always use `@Override`, I have literally no idea why I haven't done it in here. – Priv Feb 03 '20 at 20:45

0 Answers0