规范形式的领域

时间:2015-11-30 05:33:29

标签: java equals effective-java canonical-form

我正在学习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方法可以做得很便宜   比较这些规范形式而不是更昂贵的不精确比较   isons。这种技术最适用于不可变类(第15项);如果   对象可以更改,您必须使规范形式保持最新。

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

1 个答案:

答案 0 :(得分:7)

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

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;
}