Jaz*_*zer 9 java overriding equals hashcode
我目前有一个被覆盖的equals(Object)看起来像这样:
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (! (o instanceof Player)) return false;
Player p = (Player) o;
return getFirstName().equalsIgnoreCase(p.getFirstName()) &&
getLastName().equalsIgnoreCase(p.getLastName());
}
Run Code Online (Sandbox Code Playgroud)
我hashCode()目前看起来像这样:
@Override
public int hashCode() {
int result = 17;
result = 31 * result + getFirstName().toLowerCase().hashCode();
result = 31 * result + getLastName().toLowerCase().hashCode();
return result;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是关于我重写的hashCode()方法.我知道我需要hashCode()为两个对象返回相同的值,如果它们被equals(Object)方法认为是相等的.我的直觉告诉我,有些情况下这个hashCode()会违反合同.
是否有一种可接受的方法在重写的equals(Object)方法中使用equalsIgnoreCase(String)方法并生成不违反合同的哈希码?
@Override
public int hashCode() {
int result = 17;
result = 31 * result + characterwiseCaseNormalize(getFirstName()).hashCode();
result = 31 * result + characterwiseCaseNormalize(getLastName()).hashCode();
return result;
}
private static String characterwiseCaseNormalize(String s) {
StringBuilder sb = new StringBuilder(s);
for(int i = 0; i < sb.length(); i++) {
sb.setCharAt(i,Character.toLowerCase(Character.toUpperCase(sb.charAt(i))));
}
return sb.toString();
}
Run Code Online (Sandbox Code Playgroud)
这将与定义的 usinghashCode一致。原则上,根据 的合同,这似乎取决于以下情况:equalsequalsIgnoreCaseequalsIgnoreCase
Character.toLowerCase(Character.toUpperCase(c1))==Character.toLowerCase(Character.toUpperCase(c2))
Run Code Online (Sandbox Code Playgroud)
每当
Character.toLowerCase(c1)==Character.toLowerCase(c2).
Run Code Online (Sandbox Code Playgroud)
我没有证据证明这是真的,但equalsIgnoreCase 的 OpenJDK 实现实际上与此方法一致;它检查相应的字符是否相等,然后检查它们的大写版本是否相等,然后检查大写版本的小写版本是否相等。