validar minusculas mayusculas ignorar funciona equalsignorecase como java string string-comparison

minusculas - Java: String: equalsIgnoreCase vs cambiarlo todo a mayúsculas



java equals vs equalsignorecase (8)

Cuando trabajo con caracteres solo en inglés, siempre ejecuto toUpperCase() o toLowerCase() antes de comenzar a hacer comparaciones si estoy llamando a .equalsIgnoreCase() más de una vez o si estoy usando una instrucción switch . De esta manera, realiza la operación de cambio de caso solo una vez, y por lo tanto es más eficiente.

Por ejemplo, en un patrón de fábrica:

if (ignoreCase) { // If characters don''t match but case may be ignored, // try converting both characters to uppercase. // If the results match, then the comparison scan should // continue. char u1 = Character.toUpperCase(c1); char u2 = Character.toUpperCase(c2); if (u1 == u2) { continue; } // Unfortunately, conversion to uppercase does not work properly // for the Georgian alphabet, which has strange rules about case // conversion. So we need to make one last check before // exiting. if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) { continue; } }

(Usar una instrucción switch es un poco más rápido que if..else if..else bloques para la comparación de cadenas)

Me llamó la atención que hay varias formas de comparar cadenas en Java.

Acabo de acostumbrarme hace años a usar equalsIgnoreCase para evitar tener problemas con las cadenas sensibles a mayúsculas.

Otros, por otro lado, prefieren pasar todo en mayúsculas o minúsculas.

Desde donde estoy (aunque técnicamente estoy sentado), no veo una diferencia real.

¿Alguien sabe si una práctica es mejor que la otra? Y si es así, ¿por qué?


Depende del caso de uso.

Si está haciendo una comparación de una a una cadena, es probable que equalsIgnoreCase sea más rápido, ya que internamente solo pone en mayúsculas cada carácter a medida que itera a través de las cadenas (el código de abajo es de java.lang.String), que es ligeramente más rápido que en mayúsculas o minúsculas A todos ellos antes de realizar la misma comparación:

public static SuperObject objectFactory(String objectName) { switch(objectName.toUpperCase()) { case "OBJECT1": return new SubObject1(); break; case "OBJECT2": return new SubObject2(); break; case "OBJECT3": return new SubObject3(); break; } return null; }

Pero cuando se presenta una situación en la que desea realizar búsquedas en una estructura de datos llena de cadenas (especialmente cadenas que están todas en el espacio latino / ASCII de los EE. UU.) De una manera que no distingue entre mayúsculas y minúsculas, será más rápido recortar / minúsculas las cadenas para ser revisado y ponerlos en algo como un HashSet o HashMap.

Esto es mejor que llamar a equalsIgnoreCase en cada elemento de una Lista porque la leve ganancia en el rendimiento de equalsIgnoreCase () se cancela por el hecho de que básicamente estás haciendo una versión modificada de contiene () contra una matriz, que es O (n) . Con una cadena pre-normalizada puede verificar la lista completa de cadenas con una sola llamada a la que contiene () que se ejecuta en O (1).


Documentación de EqualsIgnoreCase en jdk 8

  • Compara esta cadena con otra cadena, ignorando las consideraciones de caso. Dos cadenas se consideran como caso de ignorar igual si tienen la misma longitud y los caracteres correspondientes en las dos cadenas son caso de ignorar igual.

    Dos caracteres c1 y c2 se consideran el mismo caso de ignorar si al menos uno de los siguientes es verdadero:

    • Los dos caracteres son iguales (en comparación con el operador ==)
    • La aplicación del método java.lang.CharactertoUpperCase (char) a cada carácter produce el mismo resultado
    • La aplicación del método java.lang.CharactertoLowerCase (char) a cada carácter produce el mismo resultado

Mis pensamientos:

Por lo tanto, utilizando equalsIgnoreCase, iteramos a través de las cadenas (solo si sus valores de tamaño son los mismos) comparando cada carácter. En el peor de los casos, el rendimiento será O (3cn) donde n = el tamaño de sus cadenas. No utilizaremos espacio extra.

Usando toUpper () y luego comparando si las cadenas son iguales, SIEMPRE recorre cada cadena una vez, convirtiendo todas las cadenas en superiores, luego haga una equivalencia por verificación de referencia (es igual a ()). Esto es theta (2n + c). Pero solo recuerda, cuando haces toUpperCase (), en realidad tienes que crear dos nuevas cadenas porque las cadenas en Java son inmutables.

Así que diría que equalsIgnoreCase es más eficiente y fácil de leer.

Una vez más consideraría el caso de uso, porque eso es lo que se reduce a mí. El enfoque toUpper podría ser válido en ciertos casos de uso, pero el 98% del tiempo utilizo equalsIgnoreCase ().


En cuanto al rendimiento, ambos son iguales según este post:

http://www.params.me/2011/03/stringtolowercasestringtouppercase-vs.html

Por lo tanto, me gustaría decidir en base a la capacidad de lectura del código, en algunos casos, toLowerCase () sería mejor si le pasara un valor siempre a un solo método para crear objetos, de lo contrario, es igual que IgualIgnoreCase () tenga más sentido.


Pero el problema en este último, cuando se supone que se pasa mayúscula o minúscula, no se puede confiar ciegamente en la persona que llama. Por lo tanto, debe incluir una declaración ASSERT al comienzo del método para asegurarse de que la entrada esté siempre en el caso de que esté esperando.


Tampoco es mejor, ambos tienen sus usos en diferentes escenarios.

Muchas veces, cuando tiene que hacer comparaciones de cadenas, existe la oportunidad de aplicar un masaje al menos a una de las cadenas para facilitar la comparación, y en estos casos verá cadenas convertidas en un caso particular, recortadas, etc. antes de compararlas.

Si, por otro lado, solo quieres hacer una comparación de dos cuerdas sobre la marcha que no distingue entre mayúsculas y minúsculas, siéntete libre de usar equalsIgnoreCase , eso es lo que está ahí para después de todo. Sin embargo, le equalsIgnoreCase que si está viendo un montón de equalsIgnoreCase podría ser un olor de código.


Use equalsIgnoreCase porque es más legible que convertir ambas cadenas en mayúsculas antes de una comparación. La legibilidad triunfa sobre la microoptimización .

¿Qué es más legible?

if (myString.toUpperCase().equals(myOtherString.toUpperCase())) {

o

if (myString.equalsIgnoreCase(myOtherString)) {

Creo que todos podemos estar de acuerdo en que equalsIgnoreCase es más legible.


equalsIgnoreCase evita problemas con respecto a las diferencias específicas de la configuración regional (por ejemplo, en la configuración regional turca hay dos letras "i" mayúsculas diferentes). Por otro lado, los mapas solo usan el método equals ().