Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mutable objects and hashCode

Tags:

Have the following class:

public class Member { private int x; private long y; private double d;  public Member(int x, long y, double d) {     this.x = x;     this.y = y;     this.d = d; }  @Override public int hashCode() {     final int prime = 31;     int result = 1;     result = prime * result + x;     result = (int) (prime * result + y);     result = (int) (prime * result + Double.doubleToLongBits(d));     return result; }  @Override public boolean equals(Object obj) {     if (this == obj) {         return true;     }     if (obj instanceof Member) {         Member other = (Member) obj;         return other.x == x && other.y == y                 && Double.compare(d, other.d) == 0;     }     return false; }  public static void main(String[] args) {     Set<Member> test = new HashSet<Member>();     Member b = new Member(1, 2, 3);     test.add(b);     System.out.println(b.hashCode());     b.x = 0;     System.out.println(b.hashCode());     Member first = test.iterator().next();     System.out.println(test.contains(first));     System.out.println(b.equals(first));            System.out.println(test.add(first));  } 

}

It produces the following results:
30814 29853 false true true

Because the hashCode depends of the state of the object it can no longer by retrieved properly, so the check for containment fails. The HashSet in no longer working properly. A solution would be to make Member immutable, but is that the only solution? Should all classes added to HashSets be immutable? Is there any other way to handle the situation?

Regards.

like image 723
robert Avatar asked Jan 17 '11 21:01

robert


People also ask

Can mutable objects be hashed?

– Mutable Objects Can Not Be Hashed As you know, mutable objects can't be hashed, so you have to use the immutable objects as a key in the dictionary. You can use int, string, and tuple as a key.

What is a mutable object?

A mutable object is an object whose state can be modified after it is created. Immutables are the objects whose state cannot be changed once the object is created. Strings and Numbers are Immutable.

Do all objects have Hashcode?

In Java, every object has a method hashCode that is simple to understand but still it's sometimes forgotten or misused.

What is an example of a mutable object?

If immutable objects are objects whose value can't change once created, a mutable object is an object whose value can change once created. Mutable objects are often objects that can store a collection of data. Lists (Python type list ) and dictionaries (Python type dict ) are examples of mutable objects.


1 Answers

Objects in hashsets should either be immutable, or you need to exercise discipline in not changing them after they've been used in a hashset (or hashmap).

In practice I've rarely found this to be a problem - I rarely find myself needing to use complex objects as keys or set elements, and when I do it's usually not a problem just not to mutate them. Of course if you've exposed the references to other code by this time, it can become harder.

like image 116
Jon Skeet Avatar answered Nov 06 '22 05:11

Jon Skeet