哈希映射<键,值>具有相同的输入和等于以及实现的哈希码方法,但我没有收到重复键的错误?



我有一个非常基本的示例代码来实现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

默认情况下map.put方法不会引发错误,它只是替换该键的值。查看 javadoc

如果你看到 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 中的所有条目对象都将具有相同的哈希代码,但 HashMap 使用 equals() 。此方法检查相等性,因此如果 key.equals(k) 为 true,则它将替换 Entry 类中的值对象,而不是键。因此,这样可以防止插入重复的密钥。

有关更多详细信息,请参阅链接 1 和链接 2

我希望这对你有帮助。

最新更新