dexterous-unwrapped
dexterous-unwrapped

Reputation: 83

Custom object as a key in HashMap

As we all know, we can use any Object as key in Java HashMap provided it follows equals and hashCode contract. But I have read it somewhere that - if the custom object is Immutable than this will be already taken care. So does it mean if my custom object is immutable I don't need to override hashcode and equals method to make it eligible for using it as key of my hashmap.

My understanding is this is wrong, even if my custom object is immutable it has to override hashcode and equals method in order to make it eligible for hashmap key. Please comment if you guys think otherwise.

Upvotes: 1

Views: 1139

Answers (2)

dantiston
dantiston

Reputation: 5401

Immutability means several things, but in its most basic form that you can’t change an object once it is made. This can be useful in hash lookups, but what you’re probably thinking of is persistence, which is a related but separate concept where changes to an object return a new object instead of changing the existing one (copy on write semantics).

However, to understand why either immutability or persistence can help with hash lookups, understanding how the base hash code and equality methods are implemented is required. Luckily, these implementations are usually fairly straight forward: just return the object’s position in memory. This usually doesn’t work well because two instances of a class will have two different positions in memory even if the data in the class is exactly the same. If you want to hash a class with no setters, you generally still need to calculate the equality and hash based on the members.

With persistence, this can be useful because a persistent data structure (such as hash array mapped trie) generally returns literally the same object for two structures constructed differently, e.g. set("a").add("b").id == set("a", "b").id. Subsequently, a persistent data structure can use the ID for hashing and equality effectively.

So, to answer your original question, you should implement hashCode and equals on your class without setters :-)

Upvotes: 0

Soni
Soni

Reputation: 152

Constructing the map will not be a problem, and each of your entry, unless the object's hashcode collides will be unique. However searching based on key will be a problem. As its immutable, you really cannot create the key which can match the key in the map.

{
        HashMap<ImmutableKey, String> map = new HashMap<>();
        ImmutableKey key = new ImmutableKey("A", "B");
        map.put(key, "Test");
        map.put(new ImmutableKey("A", "B"), "Test1");
        map.put(new ImmutableKey("A", "B"), "Test2");
        map.put(new ImmutableKey("A", "B"), "Test3");

        System.out.println(map);
        String data = map.get(new ImmutableKey("A", "B"));
        System.out.println(data);

}

final class ImmutableKey {
    private String key;
    private String value;

    public ImmutableKey(String key, String value) {
        this.key = key;
        this.value = value;
    }

    public String getKey() {
        return key;
    }

    public String getValue() {
        return value;
    }
}

Upvotes: 2

Related Questions