我有一个非常基本的示例代码来实现equals
和hashcode
。
有一个地图使用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
答案 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类中的值对象而不是键。因此,这样可以防止插入重复键。
我希望这会对你有所帮助。