HashMap如何在不调用equals方法的情况下替换键的值

4
public class Test
{
    public static void main(String[] args) {
        Employee e1=new Employee(1);
        Employee e2=new Employee(1);
        HashMap<Employee,String> map=new HashMap<Employee,String>();
        map.put(e1, "A");
        map.put(e1, "B");
        map.put(e2, "C");
        }
}
class Employee{
    private int id;
     Employee(int id){
         this.id=id;
     }

@Override
public int hashCode() {
    System.out.println("hascode is ="+this.id);
    return  this.id;
}
@Override
    public boolean equals(Object obj) {
    System.out.println("Equals");
        return super.equals(obj);
    }
}

当我再次放置相同的对象e1时,equals()方法不会被调用,那么如何在不检查映射中现有对象的情况下替换键e1的值B?(我认为这是equals方法的工作)


在您的第二个put中,map.put(e1, "B"),您只是用新字符串简单地覆盖了该键及其值。为什么您会期望需要equals()hashcode()呢? - Tim Biegeleisen
据我所知,在这里也没有发生任何碰撞事件,例如不同的键恰好命中相同的桶。你的put基本上是一个杀令,即只需覆盖已经存在的内容。 - Tim Biegeleisen
1个回答

5
Object.equals 方法的合同要求实现应该是自反的:

它是自反的:对于任何非空引用值x,x.equals(x) 应该返回 true

这意味着 HashMap 实现允许并且确实总是使用==首先进行比较,并且只有在该比较不为true时才调用equals方法。因此,如果您使用完全相同的对象e1替换键的值,它仅使用==比较,从不调用equals方法。
如果您查看将值放入键的HashMap实现,您会发现两次出现了这个语句的变化:
if (e.hash == hash &&
    ((k = e.key) == key || (key != null && key.equals(k))))
    break;

(首先是哈希桶中第一个键,然后在循环中迭代哈希桶中的任何其他键)

1
很好的解释,你打败了我 :) +1。 - Amit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接