I want to check if all elements of two sets of String are equal by ignoring the letter's cases.
Set<String> set1 ;
Set<String> set2 ;
.
.
.
if(set1.equals(set2)){ //all elements of set1 are equal to set2
//dosomething
}
else{
//do something else
}
However, this equality check doesn't ignore the cases of the string. Is there some other way of doing that?
Alternatively you can use TreeSet
.
public static void main(String[] args){
Set<String> s1 = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
s1.addAll(Arrays.asList(new String[] {"a", "b", "c"}));
Set<String> s2 = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
s2.addAll(Arrays.asList(new String[] {"A", "B", "C"}));
System.out.println(s1.equals(s2));
}
Unfortunately, Java does not let you supply an external "equality comparer": when you use strings, HashSet
uses only built-in hashCode
and equals
.
You can work around this problem by populating an auxiliary HashSet<String>
with strings converted to a specific (i.e. upper or lower) case, and then checking the equality on it, like this:
boolean eq = set1.size() == set2.size();
if (eq) {
Set<String> aux = new HashSet<String>();
for (String s : set1) {
aux.add(s.toUpperCase());
}
for (String s : set2) {
if (!aux.contains(s.toUpperCase())) {
eq = false;
break;
}
}
}
if (eq) {
// The sets are equal ignoring the case
}
Untested, but this is the general idea:
public boolean setEqualsIgnoreCase(Set<String> a, Set<String>b)
{
if (a.size() != b.size()) return false;
Iterator<String> ai = a.iterator();
Iterator<String> bi = b.iterator();
while(ai.hasNext())
{
if (!ai.next().equalsIgnoreCase(bi.next())) return false;
}
return true;
}
Not that I know of.
The best solution I can see, albeit over-engineered, would be to create your custom holder class holding a String
instance field (String
is final
and cannot be inherited).
You can then override equals
/ hashCode
wherein for two String
properties equalsIgnoreCase
across two instances, equals
would return true
and hashCode
s would be equal.
This implies:
hashCode
returns a hash code based on a lower (or upper) cased property's hash code.equals
is based onequalsIgnoreCase
class MyString { String s; MyString(String s) { this.s = s; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((s == null) ? 0 : s.toLowerCase().hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; MyString other = (MyString) obj; if (s == null) { if (other.s != null) return false; } else if (!s.equalsIgnoreCase(other.s)) return false; return true; } } public static void main(String[] args) { Set<MyString> set0 = new HashSet<MyString>( Arrays.asList(new MyString[] { new MyString("FOO"), new MyString("BAR") } ) ); Set<MyString> set1 = new HashSet<MyString>( Arrays.asList(new MyString[] { new MyString("foo"), new MyString("bar") } ) ); System.out.println(set0.equals(set1)); }
Output
true
... as said, over-engineered (but working).
I would build something like this (in some form of Java pseudo code):
Set<String> set1;
Set<String> set2;
if (set1.size() != set2.size()) {
return NOT_EQUAL;
} else {
Set<String> set3 = new HashSet<String>();
for (String s: set1) set3.add(s.toUpperCase());
for (String s: set2) set3.add(s.toUpperCase());
return set1.size() == set3.size() ? EQUAL : NOT_EQUAL;
}
You can use a loop and equalsIgnoreCase
testString.equalsIgnoreCase()
来源:https://stackoverflow.com/questions/24558456/java-setstring-equality-ignore-case