2010-02-08 9 views
82

he creado un programa Java para comparar dos cadenas:¿Cómo hago que mi comparación de cadenas sea insensible?

String s1 = "Hello"; 
String s2 = "hello"; 

if (s1.equals(s2)) { 
    System.out.println("hai"); 
} else { 
    System.out.println("welcome"); 
} 

Muestra "bienvenida". Entiendo que es sensible a mayúsculas y minúsculas. Pero mi problema es que quiero comparar dos cadenas sin mayúsculas y minúsculas. Es decir. Espero que la salida sea hai.

+3

Si usted sabe que es sensible a mayúsculas, podría convertir tanto a mayúsculas o minúsculas antes de comparar. – fastcodejava

+0

si usa 's1.equalsIgnoreCase (s2)' es posible que no lo haga donde sea que deba hacerse. Sugiero que encuentre de dónde proviene la cadena, un archivo o base de datos o la entrada del usuario, y conviértalo en mayúscula (o minúscula) y continúe usando .equals para la comparación. – H2ONaCl

+0

No convierta a mayúsculas/minúsculas (según lo sugerido por los comentarios anteriores), utilice el enfoque aceptado 'equalsIgnoreCase'. Lea sobre el problema turco I y problemas Unicode similares para la justificación. –

Respuesta

140
  • Lo mejor sería usar s1.equalsIgnoreCase(s2): (ver javadoc)
  • También puede convertir a los dos a/minúsculas superior y utilice s1.equals(s2)
+34

Solo tenga en cuenta que las dos soluciones no son necesariamente idénticas para todas las configuraciones regionales. String # equalsIgnoreCase no usa reglas de mayúsculas y minúsculas específicas, mientras que String # toLowerCase y #toUpperCase sí lo son. – jarnbjo

+0

@jarnbjo ¿Puedes dar un ejemplo de por qué esa diferencia? – towi

+14

Las reglas del caso específico de la configuración regional se implementan al menos para el turco y el alemán. Los turcos tratan I con y sin punto como dos letras diferentes, creando los pares de mayúsculas/minúsculas iİ y ıI, mientras que otros lenguajes tratan iI como un par y no usan las letras ı e İ. En alemán, la minúscula ß está en mayúscula como "SS". – jarnbjo

16

Tienes que utilizar el método del objeto StringcompareToIgnoreCase.

int compareValue = str1.compareToIgnoreCase(str2); 

if (compareValue == 0) que significa str1 es igual a str2.

+1

no sabía que este método también está disponible. ¡Gracias! –

2

Tenga en cuenta que es posible que desee hacer comprobaciones nulas en ellos también antes de hacer su .equals o .equalsIgnoreCase.

Un objeto String nulo no puede llamar a un método equals.

es decir:

public boolean areStringsSame(String str1, String str2) 
{ 
    if (str1 == null && str2 == null) 
     return true; 
    if (str1 == null || str2 == null) 
     return false; 

    return str1.equalsIgnoreCase(str2); 
} 
+1

Nota: las dos segundas declaraciones se pueden combinar para producir el mismo resultado como este: 'if (str1 == null || str2 == null) return false;'. – LuckyMe

+0

Código modificado para ser más limpio según el comentario anterior: era un día largo :) – VeenarM

+1

También podría cambiar la primera línea a 'if (str1 == str2) return true;' que atiende nulls y también abrevia el caso donde los dos las referencias de cadena se refieren al mismo objeto de cadena. – Barney

3

En la API de Java por defecto tiene:

String.CASE_INSENSITIVE_ORDER 

Así que no es necesario volver a escribir un comparador si tuviera que utilizar cuerdas con estructuras de datos ordenados.

String s = "some text here"; 
s.equalsIgnoreCase("Some text here"); 

Es lo que quiere para controles de igualdad puros en su propio código.

Solo para obtener más información acerca de cualquier cosa relacionada con la igualdad de cadenas en Java. La función de hashCode() de la clase java.lang.String "entre mayúsculas y minúsculas":

public int hashCode() { 
    int h = hash; 
    if (h == 0 && value.length > 0) { 
     char val[] = value; 

     for (int i = 0; i < value.length; i++) { 
      h = 31 * h + val[i]; 
     } 
     hash = h; 
    } 
    return h; 
} 

Así que si usted desea utilizar una tabla hash/HashMap con cadenas como claves, y tienen teclas como "SomeKey", " SOMEKEY "y" somekey "se consideran iguales, luego deberá envolver su cadena en otra clase (no puede extender String ya que es una clase final).Por ejemplo:

private static class HashWrap { 
    private final String value; 
    private final int hash; 

    public String get() { 
     return value; 
    } 

    private HashWrap(String value) { 
     this.value = value; 
     String lc = value.toLowerCase(); 
     this.hash = lc.hashCode(); 
    } 

    @Override 
    public boolean equals(Object o) { 
     if (this == o) return true; 
     if (o instanceof HashWrap) { 
      HashWrap that = (HashWrap) o; 
      return value.equalsIgnoreCase(that.value); 
     } else { 
      return false; 
     } 
    } 

    @Override 
    public int hashCode() { 
     return this.hash; 
    } 
} 

y luego usarlo como tal:

HashMap<HashWrap, Object> map = new HashMap<HashWrap, Object>(); 
-5
public boolean newEquals(String str1, String str2) 
{ 
    int len = str1.length(); 
int len1 = str2.length(); 
if(len==len1) 
{ 
    for(int i=0,j=0;i<str1.length();i++,j++) 
    { 
     if(str1.charAt(i)!=str2.charAt(j)) 
     return false; 
    }`enter code here` 
} 
return true; 
} 
+2

Respuesta poco clara y confusa –

+0

e incorrecta también –

8
import java.lang.String; //contains equalsIgnoreCase() 
/* 
* 
*/ 
String s1 = "Hello"; 
String s2 = "hello"; 

if (s1.equalsIgnoreCase(s2)) { 
System.out.println("hai"); 
} else { 
System.out.println("welcome"); 
} 

Ahora sería: hai

19

String.equalsIgnoreCase es la opción más práctica para el caso- ingenua comparación de cuerdas insensible.

Sin embargo, es bueno tener en cuenta que este método no realiza el plegado completo ni la descomposición, por lo que no puede realizar la coincidencia sin caja como se especifica en el estándar Unicode. De hecho, las API de JDK no proporcionan acceso a la información sobre los datos de caracteres plegables de mayúsculas y minúsculas, por lo que este trabajo se delega mejor en una biblioteca de terceros probada y probada.

Esa biblioteca es ICU, y aquí es cómo se podría implementar una utilidad de entre mayúsculas y minúsculas comparación de cadenas:

import com.ibm.icu.text.Normalizer2; 

// ... 

public static boolean equalsIgnoreCase(CharSequence s, CharSequence t) { 
    Normalizer2 normalizer = Normalizer2.getNFKCCasefoldInstance(); 
    return normalizer.normalize(s).equals(normalizer.normalize(t)); 
} 
String brook = "flu\u0308ßchen"; 
    String BROOK = "FLÜSSCHEN"; 

    assert equalsIgnoreCase(brook, BROOK); 

comparación con Naive String.equalsIgnoreCase, o String.equals en cadenas mayúsculas o convertidas a mayúsculas fallará incluso esta simple prueba.

(Ten en cuenta sin embargo que el caso predefinido sabor getNFKCCasefoldInstance plegable es independiente de la Localidad;. Para las configuraciones regionales de Turquía puede ser necesario un poco más de trabajo que implica UCharacter.foldCase)

-1

Para ser nullsafe, puede utilizar

org.apache.commons.lang.StringUtils.equalsIgnoreCase(String, String) 

o

org.apache.commons.lang3.StringUtils.equalsIgnoreCase(CharSequence, CharSequence) 
Cuestiones relacionadas