当我为同一对象重用不同的哈希码时,为什么HashMap会覆盖现有对象?

-7 java java-8

import java.util.HashMap;
import java.util.Map; 

class Geek  
{ 

    public String name; 
    public int id; 

    Geek(String name, int id)  
    { 

        this.name = name; 
        this.id = id; 
    } 

    @Override
    public boolean equals(Object obj) 
    { 

    // checking if both the object references are  
    // referring to the same object. 
    if(this == obj) 
            return true; 

        // it checks if the argument is of the  
        // type Geek by comparing the classes  
        // of the passed argument and this object. 
        // if(!(obj instanceof Geek)) return false; ---> avoid. 
        if(obj == null || obj.getClass()!= this.getClass()) 
            return false; 

        // type casting of the argument.  
        Geek geek = (Geek) obj; 

        // comparing the state of argument with  
        // the state of 'this' Object. 
        System.out.println("equals method ....."+(geek.name == this.name && geek.id == this.id));
        return (geek.name == this.name && geek.id == this.id); 
    } 

    int counter = 0;

    @Override
    public int hashCode() 
    { 

        // We are returning the Geek_id  
        // as a hashcode value. 
        // we can also return some  
        // other calculated value or may 
        // be memory address of the  
        // Object on which it is invoked.  
        // it depends on how you implement  
        // hashCode() method. 
        ++counter;
        System.out.println("counter ::>>> "+counter);
        return counter;
    } 
Run Code Online (Sandbox Code Playgroud)

驱动程序代码:

public static void main (String[] args) 
{ 

    Map<Geek, Integer> map = new HashMap<>();

    // creating the Objects of Geek class. 
    Geek g1 = new Geek("aa", 1); 
    Geek g2 = new Geek("aa", 1); 


    map.put(g1, g1.id);
    map.put(g2, g2.id);

    map.forEach((k,v) -> {
        System.out.println("key = "+k + "\n value = "+v);
    });

   /* else
    System.out.println("Both Objects are not equal. ");  */
}
Run Code Online (Sandbox Code Playgroud)

在这里,我重写了该hashCode()方法,但地图仍然只包含一个对象g2。考虑到我的哈希码每次都返回不同的整数,为什么HashMap不存储两个对象?

即使我的equals()方法对同一个对象返回true,为什么HashMap不存储两个对象?有人可以在这方面指导我吗?

Era*_*ran 7

您的counter变量是一个实例变量,因此将其初始化0为每个Geek实例。因此,无论是g1g2有相同hashCode()1,当你把他们在Map,并且被认为是由相同的HashMap,因为它们是彼此相等根据您的equals实现。

如果将更counter改为static,则hashCode()的2个实例将有所不同Geek,它们将存储在单独的地图条目中。

也就是说,您的hashCode()实现非常糟糕。如果hashCode()多次调用同一实例,则每次都会得到不同的结果!这意味着,如果您尝试将g1两次放置在中Map,则可能会将其放置两次,因为第二次put将看到不同的hashCode(),因此将在不同的存储桶中搜索密钥。