This is an interesting question from an OO perspective.
One possibility is to transfer the responsibility of the contract you want to enforce (equality without case) to the collected elements themselves, not to the list, with respect to a proper separation of concern.
You would then add a new class for your String objects (without inheritance, String
class is final) where you would implement your own hashCode/equals contract.
// Strictly speaking, this is not a String without case, since only
// hashCode/equals methods discard it. For instance, we would have
// a toString() method which returns the underlying String with the
// proper case.
public final class StringWithoutCase {
private final String underlying;
public StringWithoutCase(String underlying) {
if (null == underlying)
throw new IllegalArgumentException("Must provide a non null String");
this.underlying = underlying;
}
// implement here either delegation of responsibility from StringWithoutCase
// to String, or something like "getString()" otherwise.
public int hashCode() {
return underlying.toLowerCase().hashCode();
}
public boolean equals(Object other) {
if (! (other instanceof StringWithoutCase))
return false;
return underlying.equalsIgnoreCase(other.underlying);
}
}
The objects populating the collection would be instances of StringWithoutCase
:
Collection<StringWithoutCase> someCollection = ...
someCollection.add(new StringWithoutCase("aaa"));
someCollection.add(new StringWithoutCase("BBB"));
someCollection.add(new StringWithoutCase("cCc"));