在运行时更改Hashcode

时间:2014-11-22 13:41:07

标签: java hashmap

每个人都知道在HashMap中使用不可变类作为键是更好的,如果我们更改对象状态,那么JVM将重新计算该对象的哈希码。

有人可以在更改对象状态后,其哈希码发生变化吗? (在运行时)

3 个答案:

答案 0 :(得分:1)

public class Something {

    public String blah;

    public int hashCode() {
        return blah.hashCode();
    }
}

显然你不会完全编写这样的东西(你有一个getter和一个setter,hashCode会有点复杂,你也有一个equals() )但这符合您的问题的要求。如果您更改blah字段,则哈希码将更改。

答案 1 :(得分:1)

如果在HashMap中使用以下类的对象,并在地图中调用setState,则会出现问题。

Class MutableExample {
    private int state;

    public void setState(int s) {
        state = s;
    }

    public int hashCode() {
        return state;
    }

    public boolean equals(Object o) {
        if (!(o instanceof MutableExample)) {
            return false;
        }

        return ((MutableExample) o).state == state;
    }
}

答案 2 :(得分:0)

假设Person类是可变的,hashCodeequals是基于两个属性计算的 - firstNamelastName

Person p1 = new Person ("John", "Smith");
Person p2 = new Person ("John", "Doe");
Set<Person> persons = new HashSet<Person>();
persons.add (p1);
System.out.println(persons.contains(p2)); // prints false
p2.setLastName("Smith");
System.out.println(persons.contains(p2)); // prints true

更糟糕的是:

Person p1 = new Person ("John", "Smith");
Person p2 = new Person ("John", "Doe");
Set<Person> persons = new HashSet<Person>();
persons.add (p1);
System.out.println(persons.contains(p2)); // prints false
persons.add (p2);
p2.setLastName("Smith");
System.out.println(persons.size()); // prints 2
System.out.println(p1.equals(p2)); // prints true

HashSet被破坏 - 它包含两个相等的实例。

相同的示例适用于密钥为HashMap的{​​{1}}。