Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HashSet behavior when changing field value

I just did the following code:

import java.util.HashSet;
import java.util.Set;


public class MyClass {

    private static class MyObject {
        private int field;

        public int getField() {
            return field;
        }

        public void setField(int aField) {
            field = aField;
        }

        @Override
        public boolean equals(Object other) {
            boolean result = false;
            if (other != null && other instanceof MyObject) {
                MyObject that = (MyObject) other;
                result = (this.getField() == that.getField());
            }
            return result;
        }

        @Override
        public int hashCode() {
            return field;
        }
    }

    public static void main(String[] args) {
        Set<MyObject> mySet = new HashSet<MyObject>();
        MyObject object = new MyObject();
        object.setField(3);
        mySet.add(object);
        object.setField(5);
        System.out.println(mySet.contains(object));
        MyObject firstElement = mySet.iterator().next();
        System.out.println("The set object: " + firstElement + " the object itself: " + object);
    }

}

It prints:

false
The set object: MyClass$MyObject@5 the object itself: MyClass$MyObject@5

Basically meaning that the object is not considered to be in the set, whiile its instance itself apparantly is in the set. this means that if I insert a object in a set, then change the value of a field that participates in the calculation of the hashCode method, then the HashSet method will seize working as expected. Isn;t this too big source of possible errors? How can someone defend against such cases?

like image 219
Boris Strandjev Avatar asked Oct 25 '13 12:10

Boris Strandjev


1 Answers

Below is the quote from Set API. It explains everything.

Note: Great care must be exercised if mutable objects are used as set elements. The behavior of a set is not specified if the value of an object is changed in a manner that affects equals comparisons while the object is an element in the set. A special case of this prohibition is that it is not permissible for a set to contain itself as an element.

http://docs.oracle.com/javase/7/docs/api/java/util/Set.html

like image 158
Abhijith Nagarajan Avatar answered Oct 20 '22 08:10

Abhijith Nagarajan