作者:梦露的殇_192 | 来源:互联网 | 2022-10-20 15:44
我是Java新手(非常新)。我试图了解HashMap和类的equals方法,以及它如何覆盖重复项。请参见以下代码:
public class Student {
Integer StudentId;
String Name;
String City;
public Student(Integer studentId, String name, String city) {
super();
StudentId = studentId;
Name = name;
City = city;
}
public Integer getStudentId() {
return StudentId;
}
public String getName() {
return Name;
}
public String getCity() {
return City;
}
@Override
public int hashCode() {
System.out.println("haschode is called for " + this);
final int prime = 31;
int result = 1;
result = prime * result + ((StudentId == null) ? 0 : StudentId.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
System.out.println("equals is called for " + this);
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (StudentId == null) {
if (other.StudentId != null)
return false;
} else if (!StudentId.equals(other.StudentId))
return false;
return true;
}
@Override
public String toString() {
return "\n Student [StudentId=" + StudentId + ", Name=" + Name + ", City=" + City + "] \n";
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Map myMap = new HashMap();
myMap.put(new Student(1, "andy", "p"), "Great"); //Line 1
myMap.put(new Student(2, "sachin", "m"), "Better");
myMap.put(new Student(3, "dev", "s"), "Good");
myMap.put(new Student(1, "andy", "p"), "Excellent"); // Line 4
System.out.println(myMap);
}
}
现在,仅当我编写再次放置相同键(即“第4行”)的代码时,用main()编写的代码才调用equals方法(请参见我的代码缩进)。
为什么没有为“第2行”和“第3行”调用equals方法?它应该为每条推杆线都要求等于....对吗?
我在这里缺少一些理解,并留有以下问题:(1)为什么每个看跌期权都不调用equals方法来检查类成员的相等性?(2)谁触发Student类equals方法的调用?
1> Zircon..:
它应该为每条推杆线都要求等于....对吗?
否。HashMap equals
仅在遇到现有键和中给定的键之间的哈希冲突后才会调用put
。
改写后,它hashCode
首先调用以确定将密钥放入哪个“哈希存储桶”,如果目标存储桶中已存在密钥,则它将equals
用于比较存储桶中的密钥是否相等。
由于的值Student.hashCode()
仅基于ID,因此在插入期间,仅equals
当映射遇到Student
与插入的ID具有相同ID 的键时,才需要调用该映射。如果没有现有键与hashCode
要插入的键相同,则无需调用equals
。
这HashMap
在插入期间非常有效。这也是为什么hashCode
和之间存在契约的原因equals
:如果两个对象定义相同equals
,则它们也必须具有相同的含义hashCode
(但不一定相反)。
2> daniu..:
equals()
如果hashCode()
结果不同,则不调用。它仅与1号线和4号线相同(学生ID为1),因此equals()
被称为。
请注意,hashCode()
对于两个不同的对象可能是相同的equals()
,但是两个equals()
对象绝不能有不同hashCode()
:
如果根据equals(Object)方法,两个对象相等,则在两个对象中的每个对象上调用hashCode方法必须产生相同的整数结果。
根据equals(java.lang.Object)方法,如果两个对象不相等,则不需要在两个对象中的每个对象上调用hashCode方法必须产生不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同的整数结果可能会提高哈希表的性能。
因此,最初不同的哈希码足以在equals()
以后不调用。