Java – collection removeAll ignore case?
OK, that's my problem I have to use HashSet. I use the removeAll method to delete existing values from another collection
Before calling this method, I explicitly add values to the collection Before adding, I call on each string Touppercase(), because the values in the two lists are different There is no rhythm or reason
Once I call removeAll, I need to return the original case to the value left in set Is there a valid method without running the original list and using comparetoignorecase?
Example:
List 1:
"BOB" "Joe" "john" "MARK" "dave" "Bill"
Listing 2:
"JOE" "MARK" "DAVE"
Then, use touppercase () on strings to create a separate HashSet for each list Then call removeAll..
Set1.removeAll(set2); Set1: "BOB" "JOHN" "BILL"
I need to re list this list:
"BOB" "john" "Bill"
Any ideas would be appreciated I know it's bad. There should be a standard original list, but it's not my decision
Solution
In my original answer, I inadvertently suggested using the comparator, but this will cause TreeSet to violate the equals contract and is an error waiting to occur:
// Don't do this: Set<String> setA = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER); setA.add("hello"); setA.add("Hello"); System.out.println(setA); Set<String> setB = new HashSet<String>(); setB.add("HELLO"); // Bad code; violates symmetry requirement System.out.println(setB.equals(setA) == setA.equals(setB));
It is best to use a dedicated type:
public final class CaselessString { private final String string; private final String normalized; private CaselessString(String string,Locale locale) { this.string = string; normalized = string.toUpperCase(locale); } @Override public String toString() { return string; } @Override public int hashCode() { return normalized.hashCode(); } @Override public boolean equals(Object obj) { if (obj instanceof CaselessString) { return ((CaselessString) obj).normalized.equals(normalized); } return false; } public static CaselessString as(String s,Locale locale) { return new CaselessString(s,locale); } public static CaselessString as(String s) { return as(s,Locale.ENGLISH); } // TODO: probably best to implement CharSequence for convenience }
This code is unlikely to cause an error:
Set<CaselessString> set1 = new HashSet<CaselessString>(); set1.add(CaselessString.as("Hello")); set1.add(CaselessString.as("HELLO")); Set<CaselessString> set2 = new HashSet<CaselessString>(); set2.add(CaselessString.as("hello")); System.out.println("1: " + set1); System.out.println("2: " + set2); System.out.println("equals: " + set1.equals(set2));
Unfortunately, this is more lengthy