¿Cómo comparo cadenas en Java?

724

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 .equals()y solucionó el error.

Es ==malo? ¿Cuándo debería y no debería usarse? ¿Cual es la diferencia?

Nathan H
fuente
12
También es bueno saber que, si anula el método .equals (), asegúrese de anular el método .hashcode (), de lo contrario terminará violando la relación de equivalencia b / w equals y hashcode. Para obtener más información, consulte java doc.
Nageswaran
Dejando un enlace a mi explicación sobre por qué ==funciona de la misma manera en Objetos: stackoverflow.com/a/19966154/2284641
Johannes H.
==funcionará algunas veces, ya que Java tiene un conjunto de cadenas, donde intenta reutilizar las referencias de memoria de las cadenas de uso común. Pero ==compara que los objetos son iguales, no los valores ... también lo .equals()es el uso adecuado que desea usar.
James Oravec
Nunca use == para probar si las cadenas son las mismas, a menos que disfrute de rastrear errores sutiles y estudiar las complejidades del proceso de internamiento de cadenas de Java. "12"=="1"+2es falso (probablemente)
Flight Odyssey

Respuestas:

5563

== prueba la igualdad de referencia (si son el mismo objeto).

.equals() prueba la igualdad de valores (si son lógicamente "iguales").

Objects.equals () verifica nullantes de llamar .equals()para que no tenga que hacerlo (disponible a partir de JDK7, también disponible en Guava ).

En consecuencia, si desea probar si dos cadenas tienen el mismo valor, probablemente querrá usarlas 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 internadas cuerdas, se puede utilizar ==.

De JLS 3.10.5. Literales de cuerda :

Además, un literal de cadena siempre se refiere a la misma instancia de 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 ), están "internados" para compartir instancias únicas, utilizando el método String.intern.

También se pueden encontrar ejemplos similares en JLS 3.10.5-1 .

Otros métodos a considerar

String.equalsIgnoreCase () valor de igualdad que ignora mayúsculas y minúsculas.

String.contentEquals () compara el contenido de Stringcon el contenido de any CharSequence(disponible desde Java 1.5). Le ahorra tener que convertir su StringBuffer, etc. en una cadena antes de hacer la comparación de igualdad, pero deja la comprobación nula para usted.

Aaron Maenpaa
fuente
3
Si == verifica la igualdad de referencia, ¿por qué n == 5 tiene sentido? 5 no es una variable
Hrit Roy
2
@HritRoy Porque ==comprueba el valor de una variable. Cuando tiene un objeto, la variable que hace referencia al objeto tiene la referencia del objeto como valor . Por lo tanto, compara las referencias al comparar dos variables con ==. Al comparar un tipo de datos primitivo como int, sigue siendo el mismo caso. Una variable de tipo inttiene el entero como valor. Por lo tanto, compara los valores de dos ints usando ==. Si el intes el valor de una variable o un número mágico, no importa. Además: una referencia no es más que un número que se refiere a la memoria.
akuzminykh
718

==prueba referencias de objeto, .equals()prueba los valores de cadena.

A veces parece que ==compara valores, porque Java hace algunas cosas detrás de escena para asegurarse de que cadenas idénticas en línea sean realmente 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 las nullcadenas bien, pero llamar .equals()desde una cadena nula provocará 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 fooString1puede ser nulo, dígale al lector que escribiendo

System.out.print(fooString1 != null && fooString1.equals("bar"));

Los siguientes son más cortos, pero es menos obvio que verifica nulo:

System.out.print("bar".equals(fooString1));  // "bar" is never null
System.out.print(Objects.equals(fooString1, "bar"));  // Java 7 required
Whatsit
fuente
86
A veces parece como si "==" compara los valores, - == hacer valores siempre comparar! (¡Es solo que ciertos valores son referencias!)
aioobe
66
Por desgracia, no hay un método estático para isNullOrEmpty (), y no hay sobrecarga personalizada de operadores, lo que hace que esta parte de Java sea más complicada que en C # o Python. Y como Java no tiene métodos de extensión, no puede escribir su propia utilidad para extender java.lang.String. ¿Derecha? ¿Alguna idea sobre subclasificar String, agregar ese método de utilidad estática y luego usar MyString en su lugar? Un método estático con dos parámetros para hacer comparaciones nulas-seguras también sería bueno tener en esa subclase.
Jon Coombs
77
Maravilloso hace que sea un poco más fácil con el operador de navegación segura ( groovy.codehaus.org/... ), ?.. Eso se convertiría nullString1?.equals(nullString2);en una declaración completamente nula. Sin embargo, no ayuda si lo ha hecho validString?.equals(nullString);, eso todavía arroja una excepción.
Charles Wood
55
Métodos cortos para comparar cadenas anulables en java: stackoverflow.com/questions/11271554/…
Vadzim
55
@JonCoombs Java admite la subclasificación y la creación de métodos propios. Sin embargo, pocas clases se marcan como finalizadas debido a ciertas razones, String es una de ellas, por lo que no podemos extender. Podemos crear otra clase y hacer una clase de utilidad allí que tome dos cadenas como argumentos e implemente nuestra lógica allí. También para comprobar nulo algunas otras bibliotecas como spring y apache, buenas colecciones de métodos, se puede usar eso.
Panther
442

== compara referencias de objetos.

.equals() compara los 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 cualquier literal de cadena, la JVM primero busca ese literal en el grupo de cadenas y, si encuentra una coincidencia, se le dará la misma referencia a la nueva cadena. 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 new String("test") la declaración, se creará una nueva Cadena en el montón, y se le dará esa referencia b, por lo que bse le dará una referencia en el montón, no en el conjunto de Cadenas.

Ahora a apunta a una cadena en el grupo de cadenas mientras bseñala a una cadena en el montón. Por eso obtenemos:

if (a == b) ===> falso.

                String Pool
     "test" <-------------------- a

                   Heap
     "test" <-------------------- b

Mientras .equals() siempre compara un valor de String, por lo tanto, es cierto 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

Entonces usar .equals()siempre es mejor.

Ganesh
fuente
3
.equals () compara las dos instancias, pero igual se implementa para compararlas. Eso podría o no comparar la salida de toString.
Jacob
3
@Jacob clase Object .equals()método compara las instancias (referencias / dirección) donde como clase String .equals()métodos se reemplaza para comparar contenido (caracteres)
Satyadev
1
Es bueno señalar las diferencias entre el montón de cadenas y el montón de Java, ya que ciertamente no son lo mismo. En el conjunto de cadenas, Java intenta "almacenar en caché" los Stringobjetos para guardar la huella de la memoria, ya que Stringse sabe que es inmutable (espero, lo digo correctamente aquí). También consulte stackoverflow.com/questions/3052442/…
Roland
1
Esta es la respuesta que estaba buscando.
Weezy
¡Qué gran respuesta!
alwbtc
179

Las cadenas en Java son inmutables. Eso significa que cada vez que intente cambiar / modificar la cadena obtendrá una nueva instancia. No puede 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 se utiliza el operador == para la comparación de cadenas, no está comparando el contenido de la cadena, sino que en realidad está comparando la dirección de la memoria. Si ambos son iguales, devolverá verdadero y falso de lo contrario. Mientras que igual en cadena compara el contenido de la cadena.

Entonces, la pregunta es si todas las cadenas están en caché en el sistema, ¿cómo es que ==devuelve falso mientras que igual devuelve verdadero? Bueno, esto es posible. Si String str = new String("Testing")crea una nueva cadena como si terminara creando una nueva cadena en el caché, incluso si el caché ya contiene una cadena que tiene el mismo contenido. En breve"MyString" == new String("MyString") siempre devolverá falso.

Java también habla sobre la función interna () que se puede usar en una cadena para hacerla parte de la memoria caché. "MyString" == new String("MyString").intern() lo que devolverá verdadero.

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, encontrará errores.

Faisal Feroz
fuente
147
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; laequals() método realiza una comparación carácter por carácter de los contenidos.

Cuando llama a nuevo para ay b, cada uno obtiene una nueva referencia que apunta a la "foo"tabla de cadenas. Las referencias son diferentes, pero el contenido es el mismo.

duffymo
fuente
128

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 ese no es siempre el caso. Algunas cadenas se cargan de diferentes maneras, construidas a partir de otras cadenas, etc., por lo que nunca debe suponer que dos cadenas idénticas se almacenan en la misma ubicación.

Igual hace la comparación real para usted.

Uri
fuente
124

Sí, ==es malo para comparar cadenas (cualquier objeto realmente, a menos que sepa que son canónicos). ==solo compara referencias de objetos. .equals()pruebas de igualdad. Para las cadenas, a menudo serán las mismas, pero como has descubierto, eso no siempre está garantizado.

cletus
fuente
118

Java tiene un conjunto de cadenas bajo el cual Java gestiona la asignación de memoria para los objetos de cadena. Ver grupos de cadenas en Java

Cuando marca (compara) dos objetos con el ==operador, compara la igualdad de direcciones en el conjunto de cadenas. Si los dos objetos String tienen las mismas referencias de dirección, se devuelve true, de lo contrario false. Pero si desea comparar el contenido de dos objetos String, debe anular elequals método.

equals es en realidad el método de la clase Object, pero se reemplaza en la clase String y se proporciona una nueva definición que compara el contenido del objeto.

Example:
    stringObjectOne.equals(stringObjectTwo);

Pero tenga en cuenta que respeta el caso de String. Si desea comparar entre mayúsculas y minúsculas, debe utilizar 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
Saurabh Agarwal
fuente
77
Veo que esta es una respuesta tardía a la gran pregunta. ¿Puedo preguntar qué proporciona que ya no se menciona en las respuestas existentes?
Mysticial
66
Añadió @Mysticial equalsIgnoreCaseque podría ser informativo para los más frescos.
AmitG
103

Estoy de acuerdo con la respuesta de zacherates.

Pero lo que puede hacer es invocar intern()sus cadenas no literales.

Del ejemplo de zacherates:

// ... but they are not the same object
new String("test") == "test" ==> false 

Si internas, la igualdad de cadena no literal es true:

new String("test").intern() == "test" ==> true 
pgras
fuente
8
Esto generalmente no es una buena idea. El internado es relativamente costoso y puede (paradójicamente) >> aumentar << la huella de memoria de su JVM y aumentar los costos de GC. En la mayoría de los casos, estos superan los beneficios de rendimiento del uso ==para la comparación de cadenas.
Stephen C
101

==compara referencias de objetos en Java , y eso no es una excepción para los Stringobjetos.

Para comparar el contenido real de los objetos (incluido String), uno debe usar el equalsmétodo .

Si resulta ser una comparación de dos Stringobjetos usando , es porque los objetos fueron internados y la Máquina virtual Java tiene múltiples referencias que apuntan a la misma instancia de . No se debe esperar comparar un objeto que contiene el mismo contenido que otro objeto para evaluar como .==trueStringStringStringString==true

Coobird
fuente
99

.equals()compara los datos en una clase (suponiendo que la función esté implementada). ==compara las ubicaciones del puntero (ubicación del objeto en la memoria).

==devuelve verdadero si ambos objetos (NO HABLAR DE PRIMITIVAS) apuntan a la MISMA instancia de objeto. .equals()devuelve verdadero si los dos objetos contienen los mismos datos equals()Versus ==en Java

Eso puede ayudarte.

Matt Razza
fuente
95

==realiza una comprobación de igualdad de referencia , si los 2 objetos (cadenas en este caso) se refieren al mismo objeto en la memoria.

El equals()método verificará si el contenido o los estados de 2 objetos son iguales.

Obviamente ==es más rápido, pero (podría) dar resultados falsos en muchos casos si solo desea saber si 2 Strings contienen el mismo texto.

Definitivamente equals()se recomienda el uso del método.

No te preocupes por el rendimiento. Algunas cosas para alentar el uso String.equals():

  1. Implementación de las String.equals()primeras verificaciones para la igualdad de referencia (usando ==), y si las 2 cadenas son las mismas por referencia, ¡no se realiza ningún cálculo adicional!
  2. Si las 2 referencias de cadena no son las mismas, String.equals()luego verificaremos las longitudes de las cadenas. Esta también es una operación rápida porque la Stringclase almacena la longitud de la cadena, no es necesario contar los caracteres o los puntos de código. Si las longitudes difieren, no se realiza ninguna otra verificación, sabemos que no pueden ser iguales.
  3. Solo si llegamos hasta aquí se comparará realmente el contenido de las 2 cadenas, y esta será una comparación abreviada: 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 comprobarán más caracteres.

Cuando todo está dicho y hecho, incluso si tenemos la garantía de que las cadenas son pasantes, el uso del equals()método todavía no es esa sobrecarga que uno podría pensar, definitivamente la forma recomendada. Si desea una verificación de referencia eficiente, utilice 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).

revs icza
fuente
2
Obviously == is faster- En realidad, la implementación de las .equals(String)primeras verificaciones ==antes que cualquier otra cosa, por lo que diría que la velocidad es casi idéntica.
Razzle Shazl
2
public boolean equals(Object anObject) { if (this == anObject) { return true; } ...
Razzle Shazl
82

Si eres como yo, cuando comencé a usar Java, quería usar el operador "==" para probar 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 analizaré por qué el operador "==" no funciona al comparar cadenas de Java.

Opción 1: comparación de cadenas de Java con el método de igualdad La mayoría de las veces (tal vez el 95% del tiempo) comparo cadenas con el método de igualdad de la clase de cadena de Java, así:

if (string1.equals(string2))

Este método de cadenas iguales examina las dos cadenas de Java, y si contienen exactamente la misma cadena de caracteres, se consideran iguales.

Echando un vistazo a un ejemplo rápido de comparación de cadenas con el método de igualdad, 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 son mayúsculas o minúsculas. Cuando desee probar la igualdad de sus cadenas de esta manera que no distinga entre mayúsculas y minúsculas, use el método equalsIgnoreCase de la clase String, así:

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 Java, y es con el método compareTo de la clase String. Si las dos cadenas son exactamente iguales, el método compareTo devolverá un valor de 0 (cero). Aquí hay 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 String es igual).

Es posible que desee echar un vistazo a this ==, .equals (), compareTo () y compare ()

Mohamed E. ManSour
fuente
55
para literales de cadena Like String string1 = "foo bar"; Cadena string2 = "foo bar"; puede usar directamente el operador == para probar la igualdad de contenido
JAVA
1
En el script de Google Apps "compareTo" no es posible. He intentado instaed "es igual a" Esta fue la única solución que funciona ....
user3887038
77

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);
Khaled.K
fuente
66
¿Cómo difiere esto de otras respuestas? y por qué hacerlo de la manera que sugieres
user151019
2
@Mark La pregunta sobre la diferencia entre ==y equalsya fue respondida por otras soluciones, simplemente ofrecí una forma diferente de comparar las cadenas de una manera suelta
Khaled.K
77

El ==operador verifica si las dos referencias apuntan al mismo objeto o no. .equals()verifique el contenido real de la cadena (valor).

Tenga en cuenta que el .equals()método pertenece a la clase Object(superclase de todas las clases). Debe anularlo según los requisitos de su clase, pero para String ya está implementado y verifica si dos cadenas tienen el mismo valor o no.

  • Caso 1

    String s1 = "Stack Overflow";
    String s2 = "Stack Overflow";
    s1 == s2;      //true
    s1.equals(s2); //true

    Motivo: los literales de cadena creados sin nulo se almacenan en el grupo de cadenas en el área permgen del montón. Entonces, tanto s1 como s2 apuntan al mismo objeto en el grupo.

  • Caso 2

    String s1 = new String("Stack Overflow");
    String s2 = new String("Stack Overflow");
    s1 == s2;      //false
    s1.equals(s2); //true

    Motivo: si crea un objeto String con la newpalabra clave, se le asigna un espacio separado en el montón.

Aniket Thakur
fuente
53

==compara el valor de referencia de los objetos, mientras que el equals()método presente en la java.lang.Stringclase compara el contenido del Stringobjeto (con otro objeto).

samkit shah
fuente
15
no ser quisquilloso, pero el equals()método para Stringestá realmente en la Stringclase, no en Object. El valor predeterminado equals()en Objectno compararía que el contenido sea el mismo, y de hecho solo devuelve verdadero cuando la referencia es la misma.
Jacob Schoen
1
@JacobSchoen: el enlace anterior ya no funciona porque GrepCode está inactivo. Aquí está la alternativa para la implementación igual: [Enlace en línea] ( zgrepcode.com/java/openjdk/10.0.2/java.base/java/lang/… )
Amandeep Singh
50

Creo que cuando define un Stringdefine un objeto. Entonces necesitas usar .equals(). Cuando usa tipos de datos primitivos que usa ==pero con String(y cualquier objeto) debe usar .equals().

fabricioflores
fuente
77
"char []" no es un tipo de datos primitivo! Es una serie de "char". Y las matrices no son tipos de datos primitivos en sí mismos.
Christian
48

Si el equals()método está presente en la java.lang.Objectclase, ¡y se espera que verifique la equivalencia del estado de los objetos! Eso significa, el contenido de los objetos. Mientras ==que se espera que el operador verifique que las instancias de objeto reales sean iguales o no.

Ejemplo

Considere dos variables de referencia diferentes, str1 y str2:

str1 = new String("abc");
str2 = new String("abc");

Si usas el equals()

System.out.println((str1.equals(str2))?"TRUE":"FALSE");

Obtendrá la salida como TRUE si la usara ==.

System.out.println((str1==str2) ? "TRUE" : "FALSE");

Ahora obtendrá la FALSEsalida como, porque ambos str1y str2apuntan a dos objetos diferentes a pesar de que ambos comparten el mismo contenido de cadena. Es debido new String()a que se crea un nuevo objeto cada vez.

Rakesh KR
fuente
43

Operador == siempre está destinado a la comparación de referencias de objetos , mientras que el método de clase de cadena .equals () se anula 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)
simulacro
fuente
40

Se garantiza que todos los objetos tienen un .equals()método 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, usando ==) solo se verifican las direcciones de memoria entre dos objetos para garantizar la igualdad. La cadena anula esto.equals() método y, en lugar de utilizar la dirección de memoria, devuelve la comparación de cadenas en el nivel de caracteres para la igualdad.

Una nota clave es que las cadenas se almacenan en un conjunto de bloques, por lo que una vez que se crea una cadena, se almacena para siempre en un programa en la misma dirección. Las cadenas no cambian, son inmutables. Es por eso que es una mala idea usar la concatenación de cadenas regular si tiene una gran cantidad de procesamiento de cadenas que hacer. En su lugar, usaría las StringBuilderclases proporcionadas. Recuerde que los punteros a esta cadena pueden cambiar y si estuviera interesado en ver si dos punteros eran iguales ==, sería un buen camino a seguir. Las cuerdas no lo hacen.

James
fuente
2
"una vez que se crea una cadena, se almacena para siempre en un programa en la misma dirección" - Esto es completamente incorrecto. Solo las expresiones de cadena constantes en tiempo de compilación (posiblemente que involucran final Stringvariables) y las cadenas que su programa internamente explícitamente se almacenan en lo que usted llama un "conjunto de bloques". Todos los demás Stringobjetos están sujetos a recolección de basura una vez que no hay más referencias en vivo a ellos, al igual que cualquier otro tipo de objeto. Además, si bien se requiere la inmutabilidad para que funcione todo el mecanismo de internamiento, de lo contrario es irrelevante para esto.
Ted Hopp
La comparación de cadenas se realiza a través del método equals o equalsIgnoreCase, que en realidad compara el contenido de la cadena. Pero el signo == solo verifica los valores de referencia. Para los literales de cadena del conjunto de cadenas funcionará bien para este caso. Cadena s1 = nueva Cadena ("a"); Cadena s2 = nueva cadena ("a"); en este caso, s1 == s2 es falso, pero s1.equals (s2) es verdadero.
Shailendra Singh
39

También puedes usar el compareTo() método para comparar dos cadenas. Si el resultado 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ó cada cadena usando, new String(somestring).intern()entonces puede usar el ==operador para comparar dos cadenas, de lo contrario solo se pueden usar los métodos igual () o compareTo.

AlvaroAV
fuente
35

En Java, cuando el operador "==" se usa 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 objeto son básicamente referencias a la misma ubicación de memoria.

La clase Java String en realidad anula la implementación equals () predeterminada en la clase Object, y anula el método para que verifique solo 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 considerarán iguales.

los == operador verifica si las dos cadenas son exactamente el mismo objeto.

El .equals()método verifica si las dos cadenas tienen el mismo valor.

Lijo
fuente
1
a menos que uno de ellos sea nulo, ya que s.equals (s2) se bloqueará si s es nulo, haciendo que la comparación falle. Por supuesto, esto realmente no contradice la respuesta; Es solo una advertencia.
Jon Coombs
1
No, no se bloqueará, lanzará una NullPointerException, haciendo que la comparación no tenga lugar.
Bludzee