Java Set<String> igualdad ignorar caso
ignore-case (6)
Alternativamente, puede utilizar 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));
}
Quiero verificar si todos los elementos de dos conjuntos de String son iguales ignorando los casos de la letra.
Set<String> set1 ;
Set<String> set2 ;
.
.
.
if(set1.equals(set2)){ //all elements of set1 are equal to set2
//dosomething
}
else{
//do something else
}
Sin embargo, esta verificación de igualdad no ignora los casos de la cadena. ¿Hay alguna otra manera de hacer eso?
Desafortunadamente, Java no le permite proporcionar un "comparador de igualdad" externo: cuando usa cadenas, HashSet
usa solo hashCode
y equals
.
Puede solucionar este problema HashSet<String>
un HashSet<String>
auxiliar con cadenas convertidas en un caso específico (es decir, superior o inferior), y luego verificando la igualdad en él, como esto:
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
}
Me gustaría construir algo como esto (en alguna forma de pseudo código de 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;
}
No que yo sepa.
La mejor solución que puedo ver, aunque con una ingeniería excesiva, sería crear su clase de titular personalizado con un campo de instancia de String
(la String
es final
y no se puede heredar).
Luego puede anular equals
/ hashCode
donde para dos propiedades de String
equalsIgnoreCase
en dos instancias, equals
devolvería true
y hashCode
s sería igual.
Esto implica:
-
hashCode
devuelve un código hash basado en el código hash de unahashCode
unhashCode
inferior (o superior). equals
se basa enequalsIgnoreCase
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)); }
Salida
true
... como se dijo, sobre-diseñado (pero trabajando).
Puedes usar un loop y equalsIgnoreCase
testString.equalsIgnoreCase()
Sin probar, pero esta es la idea general:
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;
}