7

我正在学习 Effective Java,第 8 项(在覆盖 equals 时遵守一般合同)。作者已经解释的很清楚了,但是有些地方还没有详细说明。

对于这个例子,他认为一个类 CaseInsensitiveString 定义为:

public final class CaseInsensitiveString {
    private final String s;

    public CaseInsensitiveString(String s) {
        if (s == null)
            throw new NullPointerException();
        this.s = s;
    }

    // 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;
    }
    // ... // Remainder omitted
}

在文章的最后,他说:

对于某些类,例如上面的 CaseInsensitiveString,字段比较比简单的相等测试更复杂。如果是这种情况,您可能希望存储该字段的规范形式,因此 equals 方法可以对这些规范形式进行廉价的精确比较,而不是成本更高的不精确比较。这种技术最适合不可变类(第 15 条);如果对象可以更改,则必须使规范形式保持最新。

我搜索了这个术语,发现它基本上意味着某种东西的标准表示,比如目录中文件没有任何符号链接的绝对路径。但是我无法理解这个类的“规范”形式的使用,这在这里会有所帮助。有什么建议么?

4

1 回答 1

8

我认为在这个特定示例中,规范形式可能会存储字符串的小写或大写版本并对其进行比较。

private final String s;

public CaseInsensitiveString(String s) {
    //for real code probably use locale version
    this.s = s.toLowerCase();
}

这使得相等比较更便宜,因为我们可以进行精确的字符串比较而不是更昂贵的equalsIgnoreCase

// Broken - violates symmetry!
@Override
public boolean equals(Object o) {
    if (o instanceof CaseInsensitiveString)
        return s.equals(((CaseInsensitiveString) o).s);
    if (o instanceof String) // One-way interoperability!
        return s.equals((String) o);
    return false;
}
于 2015-11-30T05:36:02.010 回答