我目前有一个重写的 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());
}
我的 hashCode()
目前看起来像这样:
@Override
public int hashCode() {
int result = 17;
result = 31 * result + getFirstName().toLowerCase().hashCode();
result = 31 * result + getLastName().toLowerCase().hashCode();
return result;
}
我的问题是关于我重写的 hashCode() 方法。我知道如果 equals(Object) 方法认为两个对象相等,我需要 hashCode() 为两个对象返回相同的值。我的直觉告诉我,在某些情况下,此 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();
}
此 hashCode
将与使用 equalsIgnoreCase
定义的 equals
一致。原则上,根据 equalsIgnoreCase
的约定,这似乎依赖于
Character.toLowerCase(Character.toUpperCase(c1))==Character.toLowerCase(Character.toUpperCase(c2))
无论何时
Character.toLowerCase(c1)==Character.toLowerCase(c2).
我没有证据证明这是真的,但是 OpenJDK implementation of equalsIgnoreCase实际上是按照这种方法做的;它检查对应的字符是否相等,然后检查它们的大写版本是否相等,然后大写版本的小写版本是否相等。
关于java - 使用 equalsIgnoreCase 来检查是否相等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15628807/