Bloch 的精彩著作《Effective Java》指出,如果equals
不是对称的,那么集合的行为contains
是不确定的。
在他给出的示例中(在下面稍作修改后复制),布洛赫说他看到了“假”,但也可以看到真或异常。
如果标准未指定是否contains(Object o)
检查e.equals(o)
或o.equals(e)
针对集合中的每个项目,您可能会看到“true”,并且前者已实施。但是,Collections Javadoc明确指出它必须是后者(这就是我观察到的)。
因此,我看到的唯一可能性是“错误”或可能是异常(但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));
}
}