metodo - comparar un string con un arreglo java
¿Cómo comparo cadenas en Java? (23)
He estado usando el operador ==
en mi programa para comparar todas mis cadenas hasta ahora. Sin embargo, me encontré con un error, cambié uno de ellos en .equals()
lugar, y solucionó el error.
Es ==
malo? ¿Cuándo debería y no debería usarse? ¿Cual es la diferencia?
Creo que cuando define una String
, define un objeto. Así que necesitas usar .equals()
. Cuando usas tipos de datos primitivos, usas ==
pero con String
(y cualquier objeto) debes usar .equals()
.
El operador ==
comprueba si las dos cadenas son exactamente el mismo objeto.
El método .equals()
verificará si las dos cadenas tienen el mismo valor.
El operador ==
comprueba si las dos referencias apuntan al mismo objeto o no. .equals()
verifica el contenido real de la cadena (valor).
Tenga en cuenta que el método .equals()
pertenece a la clase Object
(super clase de todas las clases). Debe anularlo según su requisito de clase, pero para String ya está implementado, y verifica si dos cadenas tienen el mismo valor o no.
Caso 1
String s1 = ""; String s2 = ""; s1 == s2; //true s1.equals(s2); //true
Motivo: los literales de cadena creados sin nulo se almacenan en el conjunto de cadenas en el área permgen del montón. Entonces, tanto s1 como s2 apuntan al mismo objeto en el conjunto.
Caso 2
String s1 = new String(""); String s2 = new String(""); s1 == s2; //false s1.equals(s2); //true
Motivo: si crea un objeto String con la
new
palabra clave, se le asigna un espacio separado en el montón.
En Java, cuando se usa el operador “==” para comparar 2 objetos, verifica si los objetos se refieren al mismo lugar en la memoria. En otras palabras, verifica si los 2 nombres de objetos son básicamente referencias a la misma ubicación de memoria.
La clase String de Java en realidad reemplaza la implementación por defecto de equals () en la clase Object, y reemplaza el método para que solo verifique los valores de las cadenas, no sus ubicaciones en la memoria. Esto significa que si llama al método equals () para comparar 2 objetos String, entonces, siempre que la secuencia real de caracteres sea igual, ambos objetos se consideran iguales.
El operador
==
comprueba si las dos cadenas son exactamente el mismo objeto.El método
.equals()
verifica si las dos cadenas tienen el mismo valor.
Estoy de acuerdo con la respuesta de Zacherates.
Pero lo que puede hacer es llamar a intern()
en sus cadenas no literales.
De zacherates ejemplo:
// ... but they are not the same object
new String("test") == "test" ==> false
Si internas la igualdad de cadenas no literal es true
new String("test").intern() == "test" ==> true
Función:
public float simpleSimilarity(String u, String v) {
String[] a = u.split(" ");
String[] b = v.split(" ");
long correct = 0;
int minLen = Math.min(a.length, b.length);
for (int i = 0; i < minLen; i++) {
String aa = a[i];
String bb = b[i];
int minWordLength = Math.min(aa.length(), bb.length());
for (int j = 0; j < minWordLength; j++) {
if (aa.charAt(j) == bb.charAt(j)) {
correct++;
}
}
}
return (float) (((double) correct) / Math.max(u.length(), v.length()));
}
Prueba:
String a = "This is the first string.";
String b = "this is not 1st string!";
// for exact string comparison, use .equals
boolean exact = a.equals(b);
// For similarity check, there are libraries for this
// Here I''ll try a simple example I wrote
float similarity = simple_similarity(a,b);
Java tiene un grupo de cadenas bajo el cual Java administra la asignación de memoria para los objetos de cadena. Ver String Pools en Java
Cuando verifica (compara) dos objetos utilizando el operador ==
, compara la igualdad de direcciones en el conjunto de cadenas. Si los dos objetos de cadena tienen las mismas referencias de dirección, entonces devuelve true
, de lo contrario false
. Pero si desea comparar el contenido de dos objetos String, debe anular el método equals
.
equals
es en realidad el método de la clase Object, pero se anula en la clase String y se proporciona una nueva definición que compara el contenido del objeto.
Example:
stringObjectOne.equals(stringObjectTwo);
Pero ten en cuenta que respeta el caso de String. Si desea una comparación que no distinga entre mayúsculas y minúsculas, debe elegir el método equalsIgnoreCase de la clase String.
Veamos:
String one = "HELLO";
String two = "HELLO";
String three = new String("HELLO");
String four = "hello";
one == two; // TRUE
one == three; // FALSE
one == four; // FALSE
one.equals(two); // TRUE
one.equals(three); // TRUE
one.equals(four); // FALSE
one.equalsIgnoreCase(four); // TRUE
Las cuerdas en Java son inmutables. Eso significa que siempre que intente cambiar / modificar la cadena, obtendrá una nueva instancia. No puedes cambiar la cadena original. Esto se ha hecho para que estas instancias de cadena se puedan almacenar en caché. Un programa típico contiene muchas referencias de cadenas y el almacenamiento en caché de estas instancias puede disminuir la huella de memoria y aumentar el rendimiento del programa.
Cuando utiliza el operador == para la comparación de cadenas, no está comparando el contenido de la cadena, sino que está comparando la dirección de la memoria. Si ambos son iguales, devolverá verdadero y falso de lo contrario. Mientras que es igual en cadena compara el contenido de la cadena.
Entonces, la pregunta es si todas las cadenas se almacenan en caché en el sistema, ¿por qué ==
devuelve false mientras que igual devuelve true? Bueno, esto es posible. Si crea una nueva cadena como String str = new String("Testing")
, terminará creando una nueva cadena en el caché, incluso si la caché ya contiene una cadena con el mismo contenido. En resumen, "MyString" == new String("MyString")
siempre devolverá false.
Java también habla sobre la función intern () que se puede usar en una cadena para que sea parte de la memoria caché, por lo que "MyString" == new String("MyString").intern()
devolverá true.
Nota: el operador == es mucho más rápido que igual solo porque está comparando dos direcciones de memoria, pero debe asegurarse de que el código no esté creando nuevas instancias de String en el código. De lo contrario te encontrarás con errores.
Operator == siempre está destinado a la comparación de referencia de objetos , mientras que el método de clase String .equals () se reemplaza para la comparación de contenido :
String s1 = new String("abc");
String s2 = new String("abc");
System.out.println(s1 == s2); // It prints false (reference comparison)
System.out.println(s1.equals(s2)); // It prints true (content comparison)
Sí, ==
es malo para comparar cadenas (cualquier objeto realmente, a menos que sepa que son canónicos). ==
simplemente compara referencias de objetos. .equals()
pruebas de igualdad. Para las cuerdas, a menudo serán las mismas, pero como has descubierto, eso no siempre está garantizado.
Sí, es malo ...
==
significa que sus dos referencias de cadena son exactamente el mismo objeto. Es posible que haya escuchado que este es el caso porque Java mantiene una especie de tabla literal (lo que hace), pero no siempre es así. Algunas cadenas se cargan de diferentes maneras, construidas a partir de otras, etc., por lo que nunca debe asumir que dos cadenas idénticas se almacenan en la misma ubicación.
Igual hace la comparación real para ti.
Se garantiza que todos los objetos tienen un método .equals()
ya que Object contiene un método, .equals()
, que devuelve un valor booleano. El trabajo de la subclase es anular este método si se requiere una definición adicional. Sin él (es decir, utilizando ==
), solo las direcciones de memoria se verifican entre dos objetos para verificar su igualdad. La cadena anula este método .equals()
y, en lugar de utilizar la dirección de memoria, devuelve la comparación de cadenas en el nivel de carácter para la igualdad.
Una nota clave es que las cadenas se almacenan en un grupo de nudos, por lo que una vez que se crea una cadena, siempre se almacena en un programa en la misma dirección. Las cuerdas no cambian, son inmutables. Esta es la razón por la que es una mala idea usar la concatenación de cadenas normal si tiene que hacer una gran cantidad de procesamiento de cadenas. En su lugar, utilizarías las clases de StringBuilder
provistas. Recuerde que los punteros a esta cadena pueden cambiar y si le interesa ver si dos punteros son iguales ==
sería una buena manera de hacerlo. Las cuerdas en sí no lo hacen.
Si el método equals()
está presente en la clase java.lang.Object
, ¡y se espera que verifique la equivalencia del estado de los objetos! Eso significa, los contenidos de los objetos. Mientras que se espera que el operador ==
compruebe que las instancias reales del objeto son iguales o no.
Ejemplo
Considere dos variables de referencia diferentes, str1
y str2
:
str1 = new String("abc");
str2 = new String("abc");
Si usas los equals()
System.out.println((str1.equals(str2))?"TRUE":"FALSE");
Obtendrá el resultado como TRUE
si usa ==
.
System.out.println((str1==str2) ? "TRUE" : "FALSE");
Ahora obtendrás el FALSE
como salida, porque tanto str1
como str2
apuntan a dos objetos diferentes, aunque ambos comparten el mismo contenido de cadena. Es debido a la new String()
que se crea un nuevo objeto cada vez.
Si eres como yo, cuando empecé a usar Java, quería usar el operador "==" para comprobar si dos instancias de String eran iguales, pero para bien o para mal, esa no es la forma correcta de hacerlo en Java.
En este tutorial, demostraré varias formas diferentes de comparar correctamente las cadenas de Java, comenzando con el enfoque que uso la mayor parte del tiempo. Al final de este tutorial de comparación de cadenas de Java, también explicaré por qué el operador "==" no funciona al comparar cadenas de Java.
Opción 1: Comparación de la cadena Java con el método igual La mayoría de las veces (tal vez el 95% del tiempo) comparo cadenas con el método igual de la clase de la cadena Java, como esto:
if (string1.equals(string2))
Este método String Equals analiza las dos cadenas Java y, si contienen la misma cadena de caracteres, se consideran iguales.
Observando un ejemplo rápido de comparación de cadenas con el método equals, si se ejecutara la siguiente prueba, las dos cadenas no se considerarían iguales porque los caracteres no son exactamente iguales (el caso de los caracteres es diferente):
String string1 = "foo";
String string2 = "FOO";
if (string1.equals(string2))
{
// this line will not print because the
// java string equals method returns false:
System.out.println("The two strings are the same.")
}
Pero, cuando las dos cadenas contienen exactamente la misma cadena de caracteres, el método igual devolverá verdadero, como en este ejemplo:
String string1 = "foo";
String string2 = "foo";
// test for equality with the java string equals method
if (string1.equals(string2))
{
// this line WILL print
System.out.println("The two strings are the same.")
}
Opción 2: comparación de cadenas con el método equalsIgnoreCase
En algunas pruebas de comparación de cadenas querrá ignorar si las cadenas están en mayúsculas o en minúsculas. Cuando quiera probar la igualdad de sus cadenas de esta manera que no distingue entre mayúsculas y minúsculas, use el método equalsIgnoreCase de la clase String, como esto:
String string1 = "foo";
String string2 = "FOO";
// java string compare while ignoring case
if (string1.equalsIgnoreCase(string2))
{
// this line WILL print
System.out.println("Ignoring case, the two strings are the same.")
}
Opción 3: comparación de cadenas de Java con el método compareTo
También hay una tercera forma, menos común, de comparar cadenas de Java, y eso es con el método compareTo de la clase de cadena. Si las dos cadenas son exactamente iguales, el método compareTo devolverá un valor de 0 (cero). Este es un ejemplo rápido de cómo se ve este enfoque de comparación de cadenas:
String string1 = "foo bar";
String string2 = "foo bar";
// java string compare example
if (string1.compareTo(string2) == 0)
{
// this line WILL print
System.out.println("The two strings are the same.")
}
Mientras escribo sobre este concepto de igualdad en Java, es importante tener en cuenta que el lenguaje Java incluye un método igual en la clase base de objetos Java. Siempre que esté creando sus propios objetos y desee proporcionar un medio para ver si dos instancias de su objeto son "iguales", debe anular (e implementar) este método igual en su clase (de la misma manera que el lenguaje Java proporciona Este comportamiento de igualdad / comparación en el método de String Equals).
Es posible que desee ver esto ==, .equals (), compareTo () y compare ()
También puedes usar el compareTo()
para comparar dos cadenas. Si el resultado de compareTo es 0, entonces las dos cadenas son iguales, de lo contrario las cadenas que se comparan no son iguales.
El ==
compara las referencias y no compara las cadenas reales. Si creó todas las cadenas usando la new String(somestring).intern()
, puede usar el operador ==
para comparar dos cadenas, de lo contrario, solo se pueden usar los métodos igual a () o compareTo.
.equals()
compara los datos en una clase (asumiendo que la función está implementada). ==
compara ubicaciones de puntero (ubicación del objeto en la memoria).
==
devuelve verdadero si ambos objetos (NO HABLAR SOBRE PRIMITIVOS) apuntan a la MISMA instancia de objeto. .equals()
devuelve true si los dos objetos contienen los mismos datos equals()
Versus ==
en Java
Eso puede ayudarte.
==
compara el valor de referencia de los objetos, mientras que el método equals()
presente en la clase java.lang.String
compara los contenidos del objeto String
(con otro objeto).
==
compara referencias de objetos.
.equals()
compara valores de cadena.
A veces ==
da ilusiones de comparar valores de cadena, como en los siguientes casos:
String a="Test";
String b="Test";
if(a==b) ===> true
Esto se debe a que cuando crea un literal de String, la JVM primero busca ese literal en el conjunto de String y, si encuentra una coincidencia, se le dará la misma referencia a la nueva String. Debido a esto, obtenemos:
(a == b) ===> verdadero
String Pool
b -----------------> "test" <-----------------a
Sin embargo, ==
falla en el siguiente caso:
String a="test";
String b=new String("test");
if (a==b) ===> false
En este caso para la new String("test")
la nueva cadena se creará en el montón, y esa referencia se le dará a b
, por lo que a b
se le dará una referencia en el montón, no en el grupo de cadenas.
Ahora a
está apuntando a una cadena en el grupo de cadenas mientras que b
está apuntando a una cadena en el montón. Por eso conseguimos:
si (a == b) ===> falso.
String Pool
"test" <-------------------- a
Heap
"test" <-------------------- b
Mientras que .equals()
siempre compara un valor de String para que sea verdadero en ambos casos:
String a="Test";
String b="Test";
if(a.equals(b)) ===> true
String a="test";
String b=new String("test");
if(a.equals(b)) ===> true
Así que usar .equals()
siempre es mejor.
==
prueba referencias de objetos, .equals()
prueba los valores de cadena.
A veces parece que ==
compara valores, porque Java hace algunas cosas detrás de la escena para asegurarse de que las cadenas en línea idénticas sean en realidad el mismo objeto.
Por ejemplo:
String fooString1 = new String("foo");
String fooString2 = new String("foo");
// Evaluates to false
fooString1 == fooString2;
// Evaluates to true
fooString1.equals(fooString2);
// Evaluates to true, because Java uses the same object
"bar" == "bar";
¡Pero cuidado con los nulos!
==
maneja cadenas null
bien, pero llamar a .equals()
desde una cadena nula causará una excepción:
String nullString1 = null;
String nullString2 = null;
// Evaluates to true
System.out.print(nullString1 == nullString2);
// Throws a NullPointerException
System.out.print(nullString1.equals(nullString2));
Entonces, si sabe que fooString1
puede ser nulo, dígale al lector que al escribir
System.out.print(fooString1 != null && fooString1.equals("bar"));
Lo siguiente es más corto, pero es menos obvio que comprueba si es nulo (desde Java 7):
System.out.print(Objects.equals(fooString1, "bar"));
==
pruebas de igualdad de referencia (si son el mismo objeto).
.equals()
comprueba la igualdad de valores (si son lógicamente "iguales").
Objects.equals() comprueba si hay un null
antes de llamar .equals()
para que no tenga que hacerlo (disponible a partir de JDK7, también disponible en Guava ).
String.contentEquals() compara el contenido de String
con el contenido de cualquier CharSequence
(disponible desde Java 1.5).
Por consiguiente, si desea probar si dos cadenas tienen el mismo valor, probablemente querrá usar Objects.equals()
.
// These two have the same value
new String("test").equals("test") // --> true
// ... but they are not the same object
new String("test") == "test" // --> false
// ... neither are these
new String("test") == new String("test") // --> false
// ... but these are because literals are interned by
// the compiler and thus refer to the same object
"test" == "test" // --> true
// ... string literals are concatenated by the compiler
// and the results are interned.
"test" == "te" + "st" // --> true
// ... but you should really just call Objects.equals()
Objects.equals("test", new String("test")) // --> true
Objects.equals(null, "test") // --> false
Objects.equals(null, null) // --> true
Casi siempre quieres usar Objects.equals()
. En la rara situación en la que sabe que está tratando con cadenas interned , puede usar ==
.
Desde JLS 3.10.5. Literales de cuerdas :
Además, un literal de cadena siempre se refiere a la misma instancia de la clase
String
. Esto se debe a que los literales de cadena (o, más generalmente, las cadenas que son valores de expresiones constantes ( §15.28 )) se "internan" para compartir instancias únicas, utilizando el métodoString.intern
.
También se pueden encontrar ejemplos similares en JLS 3.10.5-1 .
==
realiza una verificación de igualdad de referencia , si los 2 objetos (cadenas en este caso) se refieren al mismo objeto en la memoria.
El método equals()
verificará si el contenido o los estados de 2 objetos son iguales.
Obviamente, ==
es más rápido, pero dará (podría) dar resultados falsos en muchos casos si solo quiere saber si 2 String
tienen el mismo texto.
Definitivamente se recomienda el uso del método equals()
.
No te preocupes por el rendimiento. Algunas cosas para fomentar el uso de String.equals()
:
- La implementación de
String.equals()
primero verifica la igualdad de referencia (usando==
), y si las 2 cadenas son iguales por referencia, ¡no se realizan más cálculos! - Si las 2 referencias de cadena no son iguales,
String.equals()
comprobará a continuación las longitudes de las cadenas. Esta es también una operación rápida porque la claseString
almacena la longitud de la cadena, sin necesidad de contar los caracteres o puntos de código. Si las longitudes difieren, no se realizan más comprobaciones, sabemos que no pueden ser iguales. - Solo si llegamos a este punto, los contenidos de las 2 cadenas serán realmente comparados, y esto será una comparación de mano corta: no se compararán todos los caracteres, si encontramos un carácter que no coincida (en la misma posición en las 2 cadenas) ), no se revisarán más caracteres.
Cuando todo está dicho y hecho, incluso si tenemos garantía de que las cadenas son pasantes, el uso del método equals()
todavía no es la sobrecarga que uno podría pensar, definitivamente es la forma recomendada. Si desea una verificación de referencia eficiente, use enumeraciones donde la especificación y la implementación del lenguaje garanticen que el mismo valor de enumeración será el mismo objeto (por referencia).
==
compara referencias de objetos en Java , y eso no es una excepción para los objetos String
.
Para comparar el contenido real de los objetos (incluida la String
), se debe usar el método de equals
.
Si una comparación de dos objetos String
usando ==
resulta ser true
, es porque los objetos String
fueron internados, y la Máquina Virtual de Java tiene múltiples referencias que apuntan a la misma instancia de String
. No se debe esperar que al comparar un objeto String
que contiene el mismo contenido que otro objeto String
usando ==
para evaluar como true
.
String a = new String("foo");
String b = new String("foo");
System.out.println(a == b); // prints false
System.out.println(a.equals(b)); // prints true
Asegúrate de entender por qué. Es porque la comparación ==
solo compara referencias; El método equals()
hace una comparación de contenido de carácter por carácter.
Cuando llamas nuevo para a
y b
, cada uno recibe una nueva referencia que apunta al "foo"
en la tabla de cadenas. Las referencias son diferentes, pero el contenido es el mismo.