equals
Bloch の素晴らしい本 "Effective Java"は、 が対称でない場合、コレクションの動作は不確定であると指摘していcontains
ます。
彼が示した例 (以下に若干の修正を加えて再掲) で、Bloch は「false」が表示されたが、true または Exception も同様に表示された可能性があると述べています。
コレクション内の項目ごとにcontains(Object o)
チェックするe.equals(o)
かどうかが標準で指定されておらず、前者が実装されている場合は、「true」と表示されます。o.equals(e)
ただし、Collections Javadocは、後者でなければならないと明確に述べています (そして、それは私が観察したことです)。
したがって、私が見る唯一の可能性は、「false」またはおそらく例外です (ただし、String Javadocは後者を排除しているようです)。
より広い点は理解しています。非対称性equals
がコレクションの外部のコードで問題を引き起こす可能性がありますが、彼が引用した例ではそれが見られません。
何か不足していますか?
import java.util.List;
import java.util.ArrayList;
class CIString {
private final String s;
public CIString(String s) {
this.s = s;
}
@Override public boolean equals( Object o ) {
System.out.println("Calling CIString.equals from " + this.s );
if ( o instanceof CIString)
return s.equalsIgnoreCase( ( (CIString) o).s);
if ( o instanceof String)
return s.equalsIgnoreCase( (String) o );
return false;
}
// Always override hashCode when you override equals
// This is an awful hash function (everything collides -> performance is terrible!)
// but it is semantically sound. See Item 10 from Effective Java for more details.
@Override public int hashCode() { return 42; }
}
public class CIS {
public static void main(String[] args) {
CIString a = new CIString("Polish");
String s = "polish";
List<CIString> list = new ArrayList<CIString>();
list.add(a);
System.out.println("list contains s:" + list.contains(s));
}
}