I'm testing the symmetric contract of object Equals method mentioned in the Effective Java 2nd Edition Book.
Symmetric: For any non-null reference values x and y, x.equals(y) must return true if and only if y.equals(x) returns true.
Can you explain me - why list.contains(s)
still returns false in the below code.
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;
* }
*/
@Override
public boolean equals(Object o) {
return o instanceof CaseInsensitiveString
&& ((CaseInsensitiveString) o).s.equalsIgnoreCase(s);
}
public int hashcode() {
return 0;
}
public static void main(String[] args) {
CaseInsensitiveString cis = new CaseInsensitiveString("Polish");
String s = "polish";
// System.out.println(cis.equals(s));
// System.out.println(s.equals(cis));
List<CaseInsensitiveString> list = new ArrayList<CaseInsensitiveString>();
list.add(cis);
System.out.println(list.contains(s));
}
}
The list contains a single instance of
CaseInsensitiveString
.s
is aString
instance, which cannot be equal to anyCaseInsensitiveString
sinceo instanceof CaseInsensitiveString
which appears in theequals
method will returnfalse
.If you test your code with two instances of
CaseInsensitiveString
that are constructed by strings containing the same values in different cases, you'll see that thecontains
call will returntrue
: