RandomUser
RandomUser

Reputation: 4220

Issues with using objects as Map keys with Java

Given an object we will call loc that simply holds 2 int member values, I believe I need to come up with a mechanism to generate a hashcode for the object. What I tried below doesn't work as it uses an object reference, and the 2 references will be different despite having the same members variables.

Map<Loc,String> mapTest = new HashMap<Loc,String>();
        mapTest.put(new Loc(1,2), "String 1");
        mapTest.put(new Loc(0,1), "String 2");
        mapTest.put(new Loc(2,2), "String 3");

        System.out.println("Should be String 2 " + mapTest.get(new Loc(0,1)));

After some reading it seems I need to roll my own hashcode for this object, and use that hashcode as the key. Just wanted to confirm that I am on the right track here, and if someone could guide me to simple implementations to look at that would be excellent.

Thanks

Upvotes: 2

Views: 120

Answers (5)

missingfaktor
missingfaktor

Reputation: 92016

If you want to use your type as a key type in a map, it's essential that it provides sane implementations of equals and hashCode. Fortunately, you don't have to write these implementations manually. Eclipse (and I guess other IDEs as well) can generate this boilerplate for you. Or you can even use Project Lombok for that.

Ideally the object to be used as a key in a map should be immutable. This can save you from many bugs led to by the equality issues in the context of mutation.

Upvotes: 1

adambender
adambender

Reputation: 33

Writing correct equals and hashcode methods can be tricky and the consequences of getting it wrong can be subtle and annoying. If you are able to, I would use the apache commons-lang library and take advantage of the HashCodeBuilder and EqualsBuilder classes. They will make it much easier to get the implementations right. The benefit of using these libraries is that it is much harder to get the boiler plate wrong, they hide the visual noise these methods tend to create and they make it harder for someone to come a long later and mess it up. Of course another alternative is to let your IDE generate those methods for you which works but just creates more of the noisy code vomit Java is known for.

Upvotes: 1

millimoose
millimoose

Reputation: 39950

You need to implement both hashCode() and equals(). Joshua Bloch's Effective Java should be the definitive source on the "how" part of your question, and I'm not sure if it's okay to reproduce it here, so I'll just refer you to it.

Upvotes: 0

Sean Owen
Sean Owen

Reputation: 66866

Yes, you need to override equals() and hashCode() and they need to behave consistently (that is, equal objects have to have the same hash code). No you do not use the hash coe directly; Map uses it.

Upvotes: 5

Dave Newton
Dave Newton

Reputation: 160170

Yes, you're on the right track.

See articles like this for more details.

There are a lot of different ways to implement a hashcode, you'll probably just want to combine the hashcodes of each integer primitive.

Upvotes: 1

Related Questions