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 に答える