我对hashcode()和equals()方法的实现感到困惑。 这是代码的和平。
class Employee {
int id;
String name;
public Employee(int id, String name) {
super();
this.id = id;
this.name = name;
}
@Override
public int hashCode() {
final int prime = 3;
int result = 1;
result = (prime * result) + id;
result = (prime * result) + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
Employee other = (Employee) obj;
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
[编辑1] 怀疑1 :每个比较真正意味着什么?
现在我已经实现了比较器接口及其方法。
class EmpNameComparator implements Comparator<Employee> {
@Override
public int compare(Employee a, Employee b) {
return a.name.compareToIgnoreCase(b.name);
}
}
[edit 2] Doubt2:是否要比较List&lt;&gt;中的两个辅助对象?或其他事情正在发生,它在内部做了什么?
答案 0 :(得分:3)
this == obj
检查当前对象是否是 SAME 对象。
如果它们是同一个对象,当然它们也是“平等的”。
compareToIgnoreCase比较两个String
个对象,忽略大写/小写差异:
按字典顺序比较两个字符串,忽略大小写差异。 此方法返回一个整数,其符号是调用compareTo的整数 具有大小写差异的字符串的规范化版本 通过电话被淘汰了 每个上都有Character.toLowerCase(Character.toUpperCase(字符)) 字符。
因此,当您使用自定义比较器对Employee
列表进行排序时:
Collections.sort(employeeList, new EmpNameComparator());
两名具有相同名称(忽略不同案例)的员工将被视为排序操作的同一员工。
请注意,您无法判断 John 是否会出现在 joHn 之前,或者相反。
答案 1 :(得分:1)
疑惑1:那么这里真正发生了什么,我知道这是当前对象的当前对象,为什么我们在equals中比较这个== obj。每个比较真正意味着什么?
执行this == obj
时,您基本上检查this
对象的引用和比较对象,obj
是否相同。
如果您正在调用equals()
,那么它正在比较this
对象与比较对象obj
是否相同,或者基于您覆盖的equals()
方法。例如,this.equals(obj)
当且仅当它满足true
方法中的条件时才会返回equals()
。
由于您已覆盖hashCode()
方法,因此哈希代码计算将由重写方法完成。
hashCode()
和equals()
之间存在合约,如果您要覆盖其中一个,那么您也应该覆盖其他合同,否则无法保证按预期工作。
疑问2:compareToIgnoreCase()是什么意思?是否要比较List&lt;&gt;中的两个辅助对象?或其他事情正在发生,它在内部做了什么?
这只是两个对象成员的正常String比较。在这种情况下,它将为员工a和员工b的name
对象的Employee
成员进行篡改。
与compareTo()
不同,compareToIgnoreCase()
进行不区分大小写的比较,即使两个字符串不相同,也会返回true
。例如,
fooBar
FooBAR
此处compareTo()
将返回false
,但compareToIgnoreCase()
将返回true
。