好的,这里是我的问题。我必须使用HashSet,我使用Removeall方法删除存在于另一个集合中的值。
Ok so here is my issue. I have to HashSet's, I use the Removeall method to delete values that exist in one set from the other.
在调用方法之前,我显然将值添加到集合。我在添加之前调用每个字符串上的.toUpperCase(),因为值在两个列表中都不同。
Prior to calling the method, I obviously add the values to the Sets. I call .toUpperCase() on each String before adding because the values are of different cases in both lists. There is no rhyme or reason to the case.
一旦我调用RemoveAll,我需要返回原来的案例,以保留在集合中的值。有没有一种有效的方法来执行此操作,而无需运行原始列表和使用CompareToIgnoreCase?
Once I call RemoveAll, I need to have the original cases back for the values that are left in the Set. Is there an efficient way of doing this without running through the original list and using CompareToIgnoreCase?
示例:
List1:
"BOB" "Joe" "john" "MARK" "dave" "Bill"List2:
"JOE" "MARK" "DAVE"之后,使用字符串上的toUpperCase()为每个列表创建一个单独的HashSet。然后调用RemoveAll。
After this, create a separate HashSet for each List using toUpperCase() on Strings. Then call RemoveAll.
Set1.removeAll(set2); Set1: "BOB" "JOHN" "BILL"我需要让列表看起来像这样:
I need to get the list to look like this again:
"BOB" "john" "Bill"我知道这是穷人,应该有一个标准的原始列表,但这不是我决定。谢谢!
Any ideas would be much appreciated. I know it is poor, there should be a standard for the original list but that is not for me to decide. Thank you!
推荐答案在我原来的回答中,我不建议使用 Comparator 但这会导致 TreeSet 违反 equals contract ,是一个等待发生的错误:
In my original answer, I unthinkingly suggested using a Comparator, but this causes the TreeSet to violate the equals contract and is a bug waiting to happen:
// 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 better 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 less likely to cause bugs:
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));不幸的是,这更为冗长。
This is, unfortunately, more verbose.
更多推荐
集合removeAll忽略大小写?
发布评论