如何强制HashMap使用身份(哈希码)?或建议解决方法

时间:2014-03-22 11:21:47

标签: java hashmap equality mutable

之前我已经编写了HashMap来存储一些对象,这些对象期望在存储时使用身份。即对象被对待"相同"如果Object.equals()说的话。

后来我使用内容评估范例为这些对象的类编写了hashCode()equals()方法。我的上一个HashMap立即停止工作,因为对象正在变异并变得不平等。

如何插入一些简单的解决方法,使早期的代码工作?可能有办法强制HashMap使用身份,尽管定义了equals()hashCode()方法?

1 个答案:

答案 0 :(得分:5)

简单回答:

使用IdentityHashmap

答案很长:

在可变属性上使用equalshashCode 非常糟糕的做法。事实上,如果你从逻辑上考虑这个问题,那么Map就会停止工作。

想象一下,我有ColourWrapper课程:

class ColourWrapper {

    private Color color;

    //getter/setter omitted

    @Override
    public int hashCode() {
        int hash = 3;
        hash = 83 * hash + Objects.hashCode(this.color);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final ColourWrapper other = (ColourWrapper) obj;
        if (!Objects.equals(this.color, other.color)) {
            return false;
        }
        return true;
    }

}

现在我将ColourWrapper wrapper包裹Color.RED放入我的Map。我稍后将此包装器的颜色更改为Color.GREEN。现在我想将值映射到wrapper,我该怎么做?

实际上我不能Map已经将wrapper分配给与其哈希码(-65287)对应的存储桶,现在我将包装的Color变为绿色,并且哈希码发生变化。< / p>

Map当然没有告知这个,所以当哈希码改变时,它的桶不会。它现在“迷失”了。

如果您计划在class中使用Map作为关键字,那么应该是不可变的。为了更改映射:

  1. 删除先前的映射
  2. 创建新密钥
  3. 将新地图放入地图