在第3章第8项中:
public final class CaseInsensitiveString {
private final String s;
public CaseInsensitiveString(String s) {
if (s == null)
throw new NullPointerException();
this.s = s;
}
@Override public boolean equals(Object o) {
return o instanceof CaseInsensitiveString &&
((CaseInsensitiveString) o).s.equalsIgnoreCase(s);
}
// remainder omitted
}
Run Code Online (Sandbox Code Playgroud)
在描述了该equals()方法的问题之后,他继续在比较字段的上下文中讨论这个类.
对于某些类,例如上面的CaseInsensitiveString,字段比较比简单的相等测试更复杂.如果是这种情况,您可能希望存储该字段的规范形式,因此该
equals()方法可以对这些规范形式进行廉价的精确比较,而不是更昂贵的不精确比较.这种技术最适合不可变类; 如果对象可以更改,则必须使规范形式保持最新.
所以我的问题(我仔细检查了'规范'意味着什么):Bloch在谈论什么?规范形式是什么?我已经准备好被告知答案很简单(大概是他的编辑会告诉他增加更多),但我想看到其他人这么说.
他还在hashCode()下一个项目9中提到了同样的事情.
为了在上下文中给出它,他还讨论了该equals()方法的错误版本CaseInsensitiveString:
// Broken - violates symmetry
@Override public boolean equals(Object o) {
if (o instanceof CaseInsensitiveString)
return s.equalsIgnoreCase(
((CaseInsensitiveString) o).s);
if (o instanceof String) // one-way interoperability!
return s.equalsIgnoreCase((String) o);
return false;
}
Run Code Online (Sandbox Code Playgroud)
您应该为其添加另一个final字段和存储值s.toUpperCase().这个新领域将是规范表示 s领域.方法的新实现equals()(参见下面的代码)将更便宜.此方法仅适用于不可变类.
hashCode()如果你覆盖,你不应该忘记覆盖的另一点equals().
public final class CaseInsensitiveString {
private final String s;
private final String sForEquals; //field added for simplifier equals method
public CaseInsensitiveString(String s) {
if (s == null) {
throw new IllegalArgumentException(); //NullPointerException() - bad practice
}
this.s = s;
this.sForEquals = s.toUpperCase();
}
@Override
public boolean equals(Object o) {
return o instanceof CaseInsensitiveString &&
((CaseInsensitiveString) o).sForEquals.equals(this.sForEquals);
}
@Override
public int hashCode(){
return sForEquals.hashCode();
}
// remainder omitted
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2851 次 |
| 最近记录: |