Java Set <String> случай игнорирования равенства
Я хочу проверить, равны ли все элементы из двух наборов String, игнорируя случаи букв.
Set<String> set1 ;
Set<String> set2 ;
.
.
.
if(set1.equals(set2)){ //all elements of set1 are equal to set2
//dosomething
}
else{
//do something else
}
Однако эта проверка равенства не игнорирует случаи строки. Есть ли другой способ сделать это?
Ответы
Ответ 1
В качестве альтернативы вы можете использовать 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));
}
Ответ 2
Неподтвержденный, но это общая идея:
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;
}
Ответ 3
Не то, чтобы я знал.
Лучшим решением, которое я могу видеть, хотя и с чрезмерной конструкцией, было бы создание вашего собственного класса держателей, содержащего поле экземпляра String
(String
is final
и не может быть наследовано).
Затем вы можете переопределить equals
/hashCode
, где для двух String
свойств equalsIgnoreCase
для двух экземпляров equals
вернется true
и hashCode
будет равно.
Это означает:
-
hashCode
возвращает хеш-код, основанный на нижнем (или верхнем) корпусе
хэш-код свойства.
-
equals
основан на equalsIgnoreCase
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));
}
Выход
true
... как сказано, чрезмерно спроектирован (но работает).
Ответ 4
К сожалению, Java не позволяет вам поставлять внешний "сопоставитель равенства": при использовании строк HashSet
использует только встроенные hashCode
и equals
.
Вы можете обойти эту проблему, заполнив вспомогательный HashSet<String>
строками, преобразованными в конкретный (т.е. верхний или нижний) случай, а затем проверите равенство на нем, например:
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
}
Ответ 5
Я бы построил что-то вроде этого (в некотором виде псевдо-кода Java):
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;
}
Ответ 6
Вы можете использовать цикл и equalsIgnoreCase
testString.equalsIgnoreCase()