Hashmap <key,value =“”>具有相同的输入和equals以及hashcode方法,但是我没有将错误视为重复键?

时间:2018-03-07 05:50:05

标签: java hashmap hashcode

我有一个非常基本的示例代码来实现equalshashcode

有一个地图使用Employee类的对象作为关键字。 我调试了代码,equals方法返回true重复对象。对于emp obj,所有值都相同,但我没有收到任何错误。

有人能帮助我理解这种行为吗?

以下是我的代码:

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

class Employee {
private int empId;
private String name;

    public Employee(int empId, String name)
    {
        this.empId = empId;
        this.name = name;
    }

    @Override public int hashCode()
    {
        final int prime = 31;
        int result = 1;
        result = prime * result + empId;
        result = prime * result +
          ((name == null) ? 0 : name.hashCode());
        return result;
    }

    @Override public boolean equals(Object obj)
    {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Employee other = (Employee)obj;
        if (empId != other.empId)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
}

class Address {
private int houseNo;
private String streetName;
private String city;
private int pinCode;

    public Address(int houseNo, String streetName, 
                        String city, int pinCode)
    {
        this.houseNo = houseNo;
        this.streetName = streetName;
        this.city = city;
        this.pinCode = pinCode;
    }

    public String getAddress()
    {
        return houseNo + ", " + streetName + ", " + 
                              city + ", " + pinCode;
    }

}

public class Test {
    public static String getAddress(Map map, Employee emp)
    {
        Address adrs = (Address)map.get(emp);
        return adrs.getAddress();
    }
    public static void main(String[] args)
    {
        Employee emp1 = new Employee(110, "Sajid Ali Khan");
        Address adrs1 = new Address(304, "Marol Mahrisi",
                                       "Mumbai", 400069);

        Employee emp2 = new Employee(111, "Jaspreet Singh");
        Address adrs2 = new Address(203, "Seepz", "Mumbai",
                                                  400093);

        Map<Employee, Address> map = new HashMap<>();
        map.put(emp1, adrs1);
        map.put(emp2, adrs2);
        //duplicate entry in map
        map.put(emp1, adrs1);

        System.out.println(Test.getAddress(map, new Employee(110, 
                                              "Sajid Ali Khan")));
    }
}

我也有这个:

Employee emp3 = new Employee(111, "Jaspreet Singh");
Address adrs3 = new Address(203, "Seepz", "Mumbai", 400093);

map.put(emp1, adrs1);
map.put(emp2, adrs2);
map.put(emp1, adrs1);
map.put(emp2, adrs2);
map.put(emp3, adrs3);

  System.out.println("key in map: "+map.entrySet() );

但我得到的输出为:

Size of map: [Employee@37889908=Address@3ad6a0e0, Employee@b9d91e41=Address@60dbf04d]
304, Marol Mahrisi, Mumbai, 400069

2 个答案:

答案 0 :(得分:2)

默认情况下,

map.put方法不会抛出错误,只会替换该键的值。查看javadoc

答案 1 :(得分:1)

如果你看到了HashMap的put方法的内部工作。

public V put(K key, V value) 
{
    if (key == null)
       return putForNullKey(value);
    int hash = hash(key.hashCode());
    int i = indexFor(hash, table.length);
    for (Entry<K,V> e = table[i]; e != null; e = e.next) 
    {
        Object k;
        if (e.hash == hash && ((k = e.key) == key || key.equals(k))) 
         {
             V oldValue = e.value;
             e.value = value;
             e.recordAccess(this);
             return oldValue;
          }
     }
     modCount++;
     addEntry(hash, key, value, i);
     return null;
 }

HashMap使用哈希机制,使用算法为变量或属性分配唯一代码,以便轻松检索。 真正的散列机制在应用于同一对象时应始终返回相同的hashCode()。

众所周知,HashMap不允许重复键,即使我们插入具有不同值的相同键时,也只返回最新值。 让我们举个例子:

import java.util.HashMap;
import java.util.Map;
public class HashMapEg 
{
    public static void main(String[] args) 
        {
            Map map = new HashMap();
            map.put(1,"sam");   
            map.put(1,"Ian");   
            map.put(1,"Scott");   
            map.put(null,"asdf");
            System.out.println(map);  
        }
}

对于上面的代码,您将获得输出{null = asdf,1 = Scott},因为值sam和Ian将被Scott替换。那么,这是怎么发生的呢?

LinkedList中的所有Entry对象都具有相同的哈希码,但HashMap使用equals()。此方法检查相等性,因此如果key.equals(k)为true,则它将替换Entry类中的值对象而不是键。因此,这样可以防止插入重复键。

有关详细信息,请参阅link1link2

我希望这会对你有所帮助。