Come posso confrontare le stringhe in Java?


Ho usato l'operatore == nel mio programma per confrontare tutte le mie stringhe finora. Tuttavia, mi sono imbattuto in un bug, ne ho cambiato uno in .equals() e ho corretto il bug.

È == cattivo? Quando dovrebbe e non dovrebbe essere usato? Qual è la differenza?

Author: Nathan H , 2009-02-05

23 answers

== test per l'uguaglianza di riferimento (se sono lo stesso oggetto).

.equals() test per l'uguaglianza del valore (se sono logicamente "uguali").

Oggetti.equals () controlla null prima di chiamare .equals() in modo da non dover (disponibile a partire da JDK7, disponibile anche in Guava ).

Stringa.contentEquals () confronta il contenuto di String con il contenuto di qualsiasi CharSequence (disponibile da Java 1.5).

Di conseguenza, se vuoi verificare se due stringhe hanno lo stesso valore che probabilmente vorrai usare 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

Quasi sempre vuoi usare Objects.equals(). Nella situazione rara in cui conosci hai a che fare con internate stringhe, tu puoi usare ==.

Da JLS 3.10.5. Letterali di stringa:

Inoltre, una stringa letterale si riferisce sempre alla stessa istanza della classe String. Questo perché stringhe letterali - o, più in generale, stringhe che sono i valori delle espressioni costanti (§15.28) - sono "internati" in modo da condividere istanze univoche, utilizzando il metodo String.intern.

Esempi simili si possono trovare anche in JLS 3.10.5-1 .

 5070
Author: Aaron Maenpaa, 2018-07-12 13:27:59

== verifica i riferimenti agli oggetti, .equals() verifica i valori delle stringhe.

A volte sembra che == confronti i valori, perché Java fa alcune cose dietro le quinte per assicurarsi che le stringhe in linea identiche siano in realtà lo stesso oggetto.

Per esempio:

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";

Ma attenzione ai null!

== gestisce le stringhe null bene, ma chiamare .equals() da una stringa null causerà un'eccezione:

String nullString1 = null;
String nullString2 = null;

// Evaluates to true
System.out.print(nullString1 == nullString2);

// Throws a NullPointerException
System.out.print(nullString1.equals(nullString2));

Quindi se sai che fooString1 potrebbe essere null, dì al lettore che scrivendo

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

Quanto segue è più breve, ma è meno ovvio che controlli null (da Java 7):

System.out.print(Objects.equals(fooString1, "bar"));
 636
Author: Whatsit, 2018-05-24 15:48:08

== confronta i riferimenti agli oggetti.

.equals() confronta i valori di stringa.

A volte == dà illusioni di confrontare i valori di stringa, come nei seguenti casi:

String a="Test";
String b="Test";
if(a==b) ===> true

Questo perché quando si crea una stringa letterale, la JVM cerca prima quel letterale nel pool di stringhe e, se trova una corrispondenza, lo stesso riferimento verrà dato alla nuova stringa. Per questo motivo, otteniamo:

(a = = b) = = = > vero

                       String Pool
     b -----------------> "test" <-----------------a

Tuttavia, == non riesce nel caso seguente:

String a="test";
String b=new String("test");
if (a==b) ===> false

In questo caso per new String("test") l'istruzione new String verrà creata sull'heap e quel riferimento verrà dato a b, quindi a b verrà dato un riferimento sull'heap, non nel pool di stringhe.

Ora a punta a una stringa nel pool di stringhe mentre b punta a una stringa nell'heap. A causa di ciò otteniamo:

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

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

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

Mentre .equals() confronta sempre un valore di Stringa in modo che dia vero in entrambi i casi:

String a="Test";
String b="Test";
if(a.equals(b)) ===> true

String a="test";
String b=new String("test");
if(a.equals(b)) ===> true

Quindi usare .equals() è sempre meglio.

 404
Author: Ganesh, 2018-02-08 19:15:59

L'operatore == controlla se le due stringhe sono esattamente lo stesso oggetto.

Il metodo .equals() controllerà se le due stringhe hanno lo stesso valore.

 205
Author: Clayton, 2013-12-24 07:49:45

Le stringhe in Java sono immutabili. Ciò significa che ogni volta che provi a cambiare/modificare la stringa ottieni una nuova istanza. Non è possibile modificare la stringa originale. Questo è stato fatto in modo che queste istanze di stringa possano essere memorizzate nella cache. Un programma tipico contiene molti riferimenti a stringhe e la memorizzazione nella cache di queste istanze può ridurre l'ingombro di memoria e aumentare le prestazioni del programma.

Quando si utilizza l'operatore = = per il confronto delle stringhe, non si sta confrontando il contenuto della stringa, ma in realtà confrontando l'indirizzo di memoria. Se sono entrambi uguali restituirà true e false altrimenti. Mentre equals in string confronta il contenuto della stringa.

Quindi la domanda è se tutte le stringhe sono memorizzate nella cache nel sistema, come mai == restituisce false mentre equals restituisce true? Beh, questo è possibile. Se si crea una nuova stringa come String str = new String("Testing") si finisce per creare una nuova stringa nella cache anche se la cache contiene già una stringa con lo stesso contenuto. In breve "MyString" == new String("MyString") tornerà sempre falso.

Java parla anche della funzione intern() che può essere utilizzata su una stringa per renderla parte della cache in modo che "MyString" == new String("MyString").intern() restituisca true.

Nota: == l'operatore è molto più veloce di equals solo perché stai confrontando due indirizzi di memoria, ma devi essere sicuro che il codice non stia creando nuove istanze di stringa nel codice. Altrimenti incontrerai bug.

 156
Author: Faisal Feroz, 2018-02-08 19:10:28
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

Assicurati di capire perché. È perché il confronto == confronta solo i riferimenti; il metodo equals() esegue un confronto carattere per carattere dei contenuti.

Quando si chiama new per a e b, ognuno ottiene un nuovo riferimento che punta a "foo" nella tabella delle stringhe. I riferimenti sono diversi, ma il contenuto è lo stesso.

 134
Author: duffymo, 2013-11-09 12:50:59

Sì, è brutto...

== significa che i tuoi due riferimenti di stringa sono esattamente lo stesso oggetto. Potresti aver sentito che questo è il caso perché Java mantiene una sorta di tabella letterale (cosa che fa), ma non è sempre così. Alcune stringhe vengono caricate in modi diversi, costruite da altre stringhe, ecc., quindi non devi mai presumere che due stringhe identiche siano memorizzate nella stessa posizione.

Equals fa il vero confronto per te.

 115
Author: Uri, 2017-11-19 08:16:08

Sì, == è un male per confrontare le stringhe (qualsiasi oggetto in realtà, a meno che tu non sappia che sono canonici). == confronta solo i riferimenti agli oggetti. .equals() test per l'uguaglianza. Per le stringhe, spesso saranno le stesse, ma come hai scoperto, non è sempre garantito.

 110
Author: cletus, 2014-12-17 08:28:55

Java dispone di un pool di stringhe in base al quale Java gestisce l'allocazione della memoria per gli oggetti String. Vedi Pool di stringhe in Java

Quando controlli (confronta) due oggetti usando l'operatore == confronta l'uguaglianza degli indirizzi nel pool di stringhe. Se i due oggetti String hanno gli stessi riferimenti all'indirizzo, restituisce true, altrimenti false. Ma se vuoi confrontare il contenuto di due oggetti String, devi sovrascrivere il metodo equals.

equals è in realtà il metodo della classe Object, ma viene sovrascritto nella classe String e viene fornita una nuova definizione che confronta il contenuto dell'oggetto.

Example:
    stringObjectOne.equals(stringObjectTwo);

Ma la mente rispetta il caso di stringa. Se si desidera confrontare senza maiuscolo / minuscolo, è necessario utilizzare il metodo equalsIgnoreCase della classe String.

Vediamo:

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
 105
Author: Saurabh Agarwal, 2018-02-08 19:19:10

.equals() confronta i dati in una classe (supponendo che la funzione sia implementata). == confronta le posizioni del puntatore (posizione dell'oggetto in memoria).

== restituisce true se entrambi gli oggetti (NON PARLANDO DI PRIMITIVE) puntano alla STESSA istanza dell'oggetto. .equals() restituisce true se i due oggetti contengono gli stessi dati equals() Rispetto a == in Java

Questo può aiutarti.

 92
Author: Matt Razza, 2014-12-17 08:30:43

== confronta i riferimenti agli oggetti in Java e questo non fa eccezione per gli oggetti String.

Per confrontare il contenuto effettivo degli oggetti (incluso String), è necessario utilizzare il metodo equals .

Se un confronto tra due oggetti String che utilizzano == risulta essere true, è perché gli oggetti String sono stati internati e la macchina virtuale Java ha più riferimenti alla stessa istanza di String. Non ci si dovrebbe aspettare che il confronto uno String oggetto contenente lo stesso contenuto di un altro String oggetto che utilizza == per valutare come true.

 91
Author: coobird, 2009-02-04 23:20:08

Sono d'accordo con la risposta di zacherates.

Ma quello che puoi fare è chiamare intern() sulle tue stringhe non letterali.

Dall'esempio di zacherates:

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

Se si esegue l'intern, l'uguaglianza della stringa non letterale è true

new String("test").intern() == "test" ==> true 
 88
Author: pgras, 2018-09-21 01:53:32

== esegue un controllo di uguaglianza reference , se i 2 oggetti (stringhe in questo caso) si riferiscono allo stesso oggetto nella memoria.

Il metodo equals()verificherà se i contenutio stati di 2 oggetti sono gli stessi.

Ovviamente == è più veloce, ma (potrebbe) dare risultati falsi in molti casi se vuoi solo dire se 2 Stringcontengono lo stesso testo.

Sicuramente l'uso del metodo equals() è consigliato.

Non preoccuparti delle prestazioni. Alcune cose da incoraggiare usando String.equals():

  1. L'implementazione di String.equals() verifica prima l'uguaglianza di riferimento (usando ==) e se le 2 stringhe sono uguali per riferimento, non viene eseguito alcun ulteriore calcolo!
  2. Se i riferimenti a 2 stringhe non sono gli stessi, String.equals() controllerà successivamente le lunghezze delle stringhe. Questa è anche un'operazione veloce perché la classe String memorizza la lunghezza della stringa, non è necessario contare il caratteri o punti di codice. Se le lunghezze differiscono, non viene eseguito alcun ulteriore controllo, sappiamo che non possono essere uguali.
  3. Solo se siamo arrivati a questo punto il contenuto delle 2 stringhe sarà effettivamente confrontato, e questo sarà un confronto a mano corta: non tutti i caratteri saranno confrontati, se troviamo un carattere non corrispondente (nella stessa posizione nelle 2 stringhe), non verranno controllati altri caratteri.

Quando tutto è detto e fatto, anche se abbiamo la garanzia che le stringhe sono stagisti, usando il metodo equals() non è ancora quel sovraccarico che si potrebbe pensare, sicuramente il modo consigliato. Se si desidera un controllo di riferimento efficiente, utilizzare enum dove è garantito dalla specifica e dall'implementazione della lingua che lo stesso valore enum sarà lo stesso oggetto (per riferimento).

 87
Author: icza, 2015-08-11 06:40:30

Se sei come me, quando ho iniziato a usare Java, volevo usare l'operatore "==" per verificare se due istanze di stringa erano uguali, ma nel bene e nel male, non è il modo corretto per farlo in Java.

In questo tutorial dimostrerò diversi modi per confrontare correttamente le stringhe Java, a partire dall'approccio che uso la maggior parte del tempo. Alla fine di questo tutorial di confronto delle stringhe Java discuterò anche perché l'operatore "= = " non funziona quando si confronta Java stringa.

Opzione 1: Confronto delle stringhe Java con il metodo equals Il più delle volte (forse il 95% delle volte) confronto le stringhe con il metodo equals della classe Java String, in questo modo:

if (string1.equals(string2))

Questo metodo String equals esamina le due stringhe Java e, se contengono esattamente la stessa stringa di caratteri, vengono considerate uguali.

Dando un'occhiata a un esempio di confronto rapido delle stringhe con il metodo equals, se sono stati eseguiti i seguenti test, i due le stringhe non sarebbero considerate uguali perché i caratteri non sono esattamente gli stessi (il caso dei caratteri è diverso):

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.")
}

Ma, quando le due stringhe contengono esattamente la stessa stringa di caratteri, il metodo equals restituirà true, come in questo esempio:

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.")
}

Opzione 2: Confronto delle stringhe con il metodo equalsIgnoreCase

In alcuni test di confronto delle stringhe ti consigliamo di ignorare se le stringhe sono maiuscole o minuscole. Quando vuoi prova le tue stringhe per l'uguaglianza in questo modo senza distinzione tra maiuscole e minuscole, usa il metodo equalsIgnoreCase della classe String, in questo modo:

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.")
 }

Opzione 3: Confronto delle stringhe Java con il metodo compareTo

Esiste anche un terzo modo meno comune per confrontare le stringhe Java, ed è con la classe String compareTo metodo. Se le due stringhe sono esattamente le stesse, il metodo compareTo restituirà un valore di 0 (zero). Ecco un rapido esempio di ciò che questo confronto stringa l'approccio è simile a:

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.")
}

Mentre scrivo di questo concetto di uguaglianza in Java, è importante notare che il linguaggio Java include un metodo equals nella classe di oggetti Java di base. Ogni volta che stai creando i tuoi oggetti e vuoi fornire un mezzo per vedere se due istanze del tuo oggetto sono "uguali", dovresti sovrascrivere (e implementare) questo metodo uguale nella tua classe (nello stesso modo in cui il linguaggio Java fornisce questo comportamento di uguaglianza / confronto nella stringa uguale metodo).

Si consiglia di dare un'occhiata a questo ==, .equals (), compareTo (), e confrontare()

 78
Author: Mohamed E. ManSour, 2016-03-16 15:00:47

Funzione:

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()));
}

Prova:

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);
 73
Author: Khaled.K, 2016-09-09 11:55:23

L'operatore == controlla se i due riferimenti puntano allo stesso oggetto o meno. .equals() controlla il contenuto effettivo della stringa (valore).

Si noti che il metodo .equals() appartiene alla classe Object (super classe di tutte le classi). È necessario sovrascriverlo secondo i requisiti della classe, ma per String è già implementato e controlla se due stringhe hanno lo stesso valore o meno.

  • Caso 1

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

    Motivo: i letterali stringa creati senza null sono memorizzato nel pool di stringhe nell'area permgen di heap. Quindi sia s1 che s2 puntano allo stesso oggetto nel pool.

  • Caso 2

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

    Motivo: se si crea un oggetto String utilizzando la parola chiave new viene assegnato uno spazio separato nell'heap.

 67
Author: Aniket Thakur, 2018-02-08 19:30:03

== confronta il valore di riferimento degli oggetti mentre il metodo equals() presente nella classe java.lang.String confronta il contenuto dell'oggetto String (con un altro oggetto).

 49
Author: samkit shah, 2014-03-04 20:19:10

Penso che quando definisci un String definisci un oggetto. Quindi è necessario utilizzare .equals(). Quando si utilizzano tipi di dati primitivi si utilizza == ma con String (e qualsiasi oggetto) è necessario utilizzare .equals().

 47
Author: fabricioflores, 2014-12-17 08:31:39

Se il metodo equals() è presente nella classe java.lang.Object e si prevede di verificare l'equivalenza dello stato degli oggetti! Ciò significa, il contenuto degli oggetti. Mentre l'operatore == dovrebbe verificare che le istanze dell'oggetto effettivo siano uguali o meno.

Esempio

Considera due diverse variabili di riferimento, str1 e str2:

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

Se si utilizza il equals()

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

Si otterrà l'output come TRUE se si utilizza ==.

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

Ora otterrai FALSE come output, perché sia str1 che str2 puntano a due oggetti diversi anche se entrambi condividono lo stesso contenuto di stringa. È a causa di new String() un nuovo oggetto viene creato ogni volta.

 42
Author: Rakesh KR, 2018-02-08 19:33:11

Operatore == è sempre inteso per confronto di riferimento oggetto , mentre la classe String .il metodo equals() viene sovrascritto per confronto dei contenuti :

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)
 39
Author: sham.y, 2018-02-08 19:20:12

Tutti gli oggetti sono garantiti per avere un .equals() metodo poiché oggetto contiene un metodo, .equals(), che restituisce un booleano. È compito della sottoclasse sovrascrivere questo metodo se è necessaria un'ulteriore definizione. Senza di esso (cioè usando ==) solo gli indirizzi di memoria vengono controllati tra due oggetti per l'uguaglianza. String sovrascrive questo metodo .equals() e invece di usare l'indirizzo di memoria restituisce il confronto delle stringhe a livello di carattere per l'uguaglianza.

Una nota chiave è che le stringhe sono memorizzate in un pool di blocchi, quindi una volta creata una stringa viene memorizzata per sempre in un programma allo stesso indirizzo. Le stringhe non cambiano, sono immutabili. Questo è il motivo per cui è una cattiva idea usare la concatenazione regolare delle stringhe se si ha una seria quantità di elaborazione delle stringhe da fare. Invece useresti le classi StringBuilder fornite. Ricorda che i puntatori a questa stringa possono cambiare e se fossi interessato a vedere se due puntatori erano uguali == sarebbe un buon modo per andare. Stringa loro stessi non lo fanno.

 36
Author: James, 2018-02-08 19:12:44

È anche possibile utilizzare il metodo compareTo() per confrontare due stringhe. Se il risultato compareTo è 0, le due stringhe sono uguali, altrimenti le stringhe confrontate non sono uguali.

Il == confronta i riferimenti e non confronta le stringhe effettive. Se hai creato ogni stringa usando new String(somestring).intern(), puoi usare l'operatore == per confrontare due stringhe, altrimenti è possibile utilizzare solo i metodi equals() o compareTo.

 36
Author: AlvaroAV, 2018-02-08 19:21:07

In Java, quando il "==" operatore viene utilizzato per confrontare 2 oggetti, controlla per vedere se gli oggetti si riferiscono alla stessa posizione in memoria. In altre parole, controlla se i 2 nomi di oggetti sono fondamentalmente riferimenti alla stessa posizione di memoria.

La classe Java String in realtà sovrascrive l'implementazione predefinita equals() nella classe Object – e sovrascrive il metodo in modo che controlli solo i valori delle stringhe, non le loro posizioni in memoria. Ciò significa che se chiama il metodo equals () per confrontare 2 oggetti Stringa, quindi finché la sequenza effettiva di caratteri è uguale, entrambi gli oggetti sono considerati uguali.

L'operatore == controlla se le due stringhe sono esattamente lo stesso oggetto.

Il metodo .equals() controlla se le due stringhe hanno lo stesso valore.

 34
Author: Lijo, 2014-08-04 00:48:38