更改字段值时的HashSet行为

Bor*_*jev 6 java collections hashset data-structures

我刚刚做了以下代码:

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);
    }

}
Run Code Online (Sandbox Code Playgroud)

它打印:

false
The set object: MyClass$MyObject@5 the object itself: MyClass$MyObject@5
Run Code Online (Sandbox Code Playgroud)

基本上意味着object不被认为是在集合中,而它的实例本身就是在集合中.这意味着如果我在一个集合中插入一个对象,然后更改参与该hashCode方法计算的字段的值,那么该HashSet方法将按预期抓住工作.这不是可能错误的根源吗?有人如何防范此类案件?

Abh*_*jan 5

以下是 Set API 的引用。它解释了一切。

注意:如果将可变对象用作集合元素,则必须格外小心。如果对象的值以影响等于比较的方式更改,而该对象是集合中的元素,则不会指定集合的​​行为。此禁止的一个特殊情况是不允许集合将其自身包含为元素。

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