Come faccio a confrontare le stringhe in Java?


724

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

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


12
Inoltre, è bene sapere che, se si sostituisce il metodo .equals (), assicurarsi di sovrascrivere il metodo .hashcode (), altrimenti si finirà per violare la relazione di equivalenza b / n uguale a e hashcode. Per maggiori informazioni consultare java doc.
Nageswaran,

Lasciando un link alla mia spiegazione sul perché ==funziona come su Oggetti: stackoverflow.com/a/19966154/2284641
Johannes H.

==funzionerà qualche volta, poiché java ha un pool di stringhe, in cui tenta di riutilizzare i riferimenti di memoria delle stringhe comunemente utilizzate. Ma ==confronta che gli oggetti sono uguali, non i valori ... quindi .equals()è l'uso corretto che si desidera utilizzare.
James Oravec,

Non usare mai == per verificare se le stringhe sono uguali, a meno che non ti piace rintracciare gli errori sottili e studiare la complessità del processo di internamento della stringa Java. "12"=="1"+2è falso (probabilmente)
Flight Odyssey il

Risposte:


5562

== verifica l'uguaglianza di riferimento (indipendentemente dal fatto che siano lo stesso oggetto).

.equals() verifica l'uguaglianza dei valori (se sono logicamente "uguali").

Objects.equals () verifica nullprima di chiamare, .equals()quindi non è necessario (disponibile da JDK7, disponibile anche in Guava ).

Di conseguenza, se si desidera verificare se due stringhe hanno lo stesso valore, è consigliabile utilizzarle 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

Hai quasi sempre voglia di usare Objects.equals(). Nella rara situazione in cui sai che hai a che fare con stringhe internate , puoi usare ==.

Da JLS 3.10.5. Letterali per archi :

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

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

Altri metodi da considerare

String.equalsIgnoreCase () valore uguaglianza che ignora il caso.

String.contentEquals () confronta il contenuto di Stringcon il contenuto di qualsiasi CharSequence(disponibile da Java 1.5). Ti evita di dover trasformare StringBuffer, ecc. In una stringa prima di fare il confronto di uguaglianza, ma lascia il controllo null a te.


3
Se == verifica l'uguaglianza di riferimento, perché n == 5 ha senso? 5 non è una variabile
Hrit Roy,

2
@HritRoy Perché ==controlla il valore di una variabile. Quando si dispone di un oggetto, la variabile che fa riferimento l'oggetto ha di riferimento dell'oggetto come valore . Pertanto, si confrontano i riferimenti quando si confrontano due variabili con ==. Quando si confronta un tipo di dati primitivo come int, è sempre lo stesso caso. Una variabile di tipo intha l'intero come valore. Pertanto, si confrontano i valori di due intsecondi usando ==. Se intè il valore di una variabile o di un numero magico non importa. Inoltre: un riferimento non è altro che un numero che si riferisce alla memoria.
Akuzminykh

718

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

A volte sembra che ==confronta i valori, perché Java fa alcune cose dietro le quinte per assicurarsi che stringhe in linea identiche siano effettivamente 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 nulli!

==gestisce nullbene le stringhe, ma chiamare .equals()da una stringa nulla 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 fooString1potrebbe essere nullo, dillo al lettore scrivendolo

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

Di seguito sono più brevi, ma è meno ovvio che verifica la presenza di null:

System.out.print("bar".equals(fooString1));  // "bar" is never null
System.out.print(Objects.equals(fooString1, "bar"));  // Java 7 required

86
A volte sembra come se "==" confronta i valori, - == fare valori sempre confrontare! (È solo che alcuni valori sono riferimenti!)
aioobe

6
Purtroppo, non esiste un metodo statico per isNullOrEmpty () e nessun sovraccarico personalizzato degli operatori, che rende questa parte di Java più complessa rispetto a C # o Python. E poiché Java non ha metodi di estensione, non è possibile scrivere la propria utilità per estendere java.lang.String. Giusto? Qualche idea sulla sottoclasse di String, l'aggiunta di quel metodo di utilità statica e quindi sempre l'utilizzo di MyString? Un metodo statico con due parametri per fare confronti null-safe sarebbe bello avere anche in quella sottoclasse.
Jon Coombs,

7
Groovy rende questo un po 'più facile con l' operatore di navigazione sicura ( groovy.codehaus.org/... ), ?.. Ciò si convertirà nullString1?.equals(nullString2);in un'istruzione completamente nulla. Tuttavia, non è utile se lo hai validString?.equals(nullString);- questo genera ancora un'eccezione.
Charles Wood,

5
Metodi brevi per confrontare stringhe nullable in java: stackoverflow.com/questions/11271554/…
Vadzim

5
@JonCoombs Java supporta la sottoclasse e la creazione del proprio metodo. Tuttavia, poche classi sono contrassegnate come finali per alcuni motivi, String è una di queste, quindi non possiamo estenderle. Possiamo creare un'altra classe e creare lì una classe di utilità che accetta due stringhe come argomenti e implementa la nostra logica lì. Anche per il controllo null alcune altre librerie come spring e apache ha buone raccolte di metodi, si può usare quello.
Pantera,

442

== confronta i riferimenti agli oggetti.

.equals() confronta i valori di stringa.

A volte ==dà l'illusione di confrontare i valori di String, come nei seguenti casi:

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

Questo perché quando si crea un valore letterale String, la JVM cerca prima quel valore letterale nel pool String 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 seguente caso:

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

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

Ora apunta a una stringa nel pool di stringhe mentre bpunta a una stringa sull'heap. Per questo motivo otteniamo:

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

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

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

Mentre .equals()confronta sempre un valore di String in modo che sia 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.


3
.equals () confronta le due istanze, tuttavia equals è implementato per confrontarle. Questo potrebbe o meno confrontare l'output di toString.
Jacob

3
Il .equals()metodo della classe oggetto @Jacob confronta le istanze (riferimenti / indirizzo) in cui i .equals()metodi della classe String vengono sovrascritti per confrontare il contenuto (caratteri)
Satyadev

1
Buona puntamento fuori String piscina rispetto differenze Java mucchio come sono certamente non è la stessa cosa. Nel pool di stringhe Java tenta di "memorizzare nella cache" gli Stringoggetti per risparmiare il footprint di memoria come Stringè noto per essere immutabile (spero, lo dico correttamente qui). Controlla anche stackoverflow.com/questions/3052442/…
Roland

1
Questa è la risposta che stavo cercando.
Weezy,

Che grande risposta!
alwbtc,


179

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 il footprint di memoria e aumentare le prestazioni del programma.

Quando si utilizza l'operatore == per il confronto delle stringhe non si confrontano i contenuti della stringa, ma si sta effettivamente confrontando l'indirizzo di memoria. Se sono entrambi uguali, restituirà vero e falso altrimenti. Considerando che uguale a stringa confronta il contenuto della stringa.

Quindi la domanda è se tutte le stringhe sono memorizzate nella cache del sistema, come mai ==restituisce false mentre uguale restituisce true? Bene, 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")restituirà sempre falso.

Java parla anche della funzione intern () che può essere utilizzata su una stringa per renderla parte della cache, quindi "MyString" == new String("MyString").intern()restituirà true.

Nota: == l'operatore è molto più veloce di uguale solo perché si stanno confrontando due indirizzi di memoria, ma è necessario assicurarsi che il codice non stia creando nuove istanze String nel codice. Altrimenti incontrerai dei bug.


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

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

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


128

Sì, è male ...

==significa che i tuoi riferimenti a due stringhe 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 si deve mai supporre che due stringhe identiche siano memorizzate nella stessa posizione.

Equals fa il vero confronto per te.


124

Sì, ==è male per confrontare le stringhe (qualsiasi oggetto in realtà, a meno che tu non sappia che sono canoniche). ==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.


118

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

Quando si controlla (confronta) due oggetti usando l' ==operatore, confronta l'uguaglianza degli indirizzi nel pool di stringhe. Se i due oggetti String hanno gli stessi riferimenti di indirizzo, allora ritorna true, altrimenti false. Ma se si desidera confrontare il contenuto di due oggetti String, è necessario sovrascrivere il equalsmetodo.

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 attenzione rispetta il caso di String. Se si desidera un confronto senza distinzione tra maiuscole e minuscole, è necessario scegliere 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

7
Vedo che questa è una risposta tardiva a una grande domanda. Posso chiedere cosa prevede che non sia già menzionato nelle risposte esistenti?
Mistico

6
@Mysticial ha aggiunto equalsIgnoreCaseche potrebbe essere informativo per i più freschi.
AmitG

103

Sono d'accordo con la risposta degli zacherati.

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

Dall'esempio di zacherates:

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

Se internate l'uguaglianza String non letterale è true:

new String("test").intern() == "test" ==> true 

8
Questa non è generalmente una buona idea. Il interning è relativamente costoso e può (paradossalmente) >> aumentare << il footprint di memoria della tua JVM e aumentare i costi GC. Nella maggior parte dei casi, questi superano i benefici prestazionali derivanti dall'uso ==per il confronto delle stringhe.
Stephen C,

101

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

Per confrontare il contenuto effettivo di oggetti (inclusi String), si deve utilizzare il equalsmetodo .

Se un confronto di due Stringoggetti usando ==risulta essere true, ciò è dovuto al fatto che gli Stringoggetti sono stati internati e che Java Virtual Machine ha più riferimenti puntano alla stessa istanza di String. Non ci si dovrebbe aspettare che confrontando un Stringoggetto contenente gli stessi contenuti di un altro Stringoggetto usando ==per valutare come true.


99

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

==restituisce vero se entrambi gli oggetti (NON PARLANO SUI PRIMITIVI) puntano all'istanza dell'oggetto SAME. .equals()restituisce true se i due oggetti contengono gli stessi dati equals()Versus ==in Java

Questo potrebbe aiutarti.


95

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

Il equals()metodo verificherà se i contenuti o gli stati di 2 oggetti sono uguali.

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

Sicuramente equals()si consiglia l'uso del metodo.

Non preoccuparti per le prestazioni. Alcune cose per incoraggiare l'uso String.equals():

  1. Implementazione dei String.equals()primi controlli per l'uguaglianza di riferimento (utilizzo ==) e se le 2 stringhe sono uguali per riferimento, non viene eseguito alcun ulteriore calcolo!
  2. Se i riferimenti a 2 stringhe non coincidono, String.equals()verranno verificate le lunghezze delle stringhe. Anche questa è un'operazione veloce perché la Stringclasse memorizza la lunghezza della stringa, senza bisogno di contare i caratteri o i 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 verrà effettivamente confrontato, e questo sarà un confronto a breve termine: non tutti i personaggi verranno 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 siano stagisti, l'utilizzo del equals()metodo non è ancora quell'overhead che si potrebbe pensare, sicuramente il modo raccomandato. Se si desidera un controllo di riferimento efficiente, utilizzare enum dove è garantito dalle specifiche della lingua e dall'implementazione che lo stesso valore enum sarà lo stesso oggetto (per riferimento).


2
Obviously == is faster- in realtà l'implementazione dei .equals(String)primi controlli ==prima di ogni altra cosa, quindi direi che la velocità è praticamente identica.
Razzle Shazl,

2
public boolean equals(Object anObject) { if (this == anObject) { return true; } ...
Razzle Shazl,

82

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

In questo tutorial mostrerò diversi modi per confrontare correttamente le stringhe Java, a partire dall'approccio che uso la maggior parte delle volte. Alla fine di questo tutorial di confronto delle stringhe Java, parlerò anche del motivo per cui l'operatore "==" non funziona quando si confrontano le stringhe Java.

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 String Java, in questo modo:

if (string1.equals(string2))

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

Dando un'occhiata a un rapido esempio di confronto di stringhe con il metodo equals, se il seguente test fosse eseguito, le due 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 vorrai ignorare se le stringhe sono maiuscole o minuscole. Quando si desidera verificare l'uguaglianza delle stringhe in questo modo senza distinzione tra maiuscole e minuscole, utilizzare 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 il metodo compareTo della classe String. Se le due stringhe sono esattamente le stesse, il metodo compareTo restituirà un valore pari a 0 (zero). Ecco un breve esempio di come appare questo approccio al confronto di stringhe:

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 sto scrivendo su questo concetto di uguaglianza in Java, è importante notare che il linguaggio Java include un metodo uguale 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 nel metodo String equals).

Puoi dare un'occhiata a this ==, .equals (), compareTo () e compare ()


5
per letterali stringa Come String string1 = "foo bar"; String string2 = "foo bar"; puoi utilizzare direttamente l'operatore == per testare l'uguaglianza dei contenuti
JAVA

1
In google apps lo script "compareTo" non è possibile. Ho provato instabile "uguale" Questa era l'unica soluzione che funziona ....
user3887038

77

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

Test:

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

6
In cosa differisce dalle altre risposte? e perché lo fai come suggerisci tu
user151019

2
@Mark Alla domanda sulla differenza tra ==ed equalsè già stata data risposta da altre soluzioni, ho appena offerto un modo diverso di confrontare le stringhe in modo libero
Khaled.K,

77

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

Si noti che il .equals()metodo appartiene alla classe Object(super classe di tutte le classi). È necessario sovrascriverlo come richiesto dalla 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 valori letterali di stringa creati senza null vengono memorizzati nel pool di stringhe nell'area permgen dell'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 newparola chiave, nell'heap viene assegnato uno spazio separato.


53

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


15
non essere pignoli, ma il equals()metodo Stringè in realtà nella Stringclasse, non in Object. L'impostazione predefinita equals()in Objectnon confrontare che i contenuti sono gli stessi, e di fatto solo restituisce true quando il riferimento è lo stesso.
Jacob Schoen,

1
@JacobSchoen: il link sopra non funziona più perché GrepCode non è attivo. Ecco l'alternativa per egual Implementation: [Inline Link] ( zgrepcode.com/java/openjdk/10.0.2/java.base/java/lang/… )
Amandeep Singh

50

Penso che quando si definisce un Stringsi definisce un oggetto. Quindi devi usare.equals() . Quando usi tipi di dati primitivi che usi ==ma con String(e qualsiasi oggetto) devi usare .equals().


7
"char []" non è un tipo di dati primitivo! È un array di "char". E le matrici non sono tipi di dati primitivi.
Christian,

48

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

Esempio

Considera due diverse variabili di riferimento str1estr2 :

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

Se si utilizza il equals()

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

Otterrai l'output come TRUEse lo usassi== .

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

Ora otterrai l' FALSEoutput come, perché entrambi str1e str2puntano a due oggetti diversi anche se entrambi condividono lo stesso contenuto di stringa. È a causa di new String()un nuovo oggetto creato ogni volta.


43

Operatore == è sempre pensato per il confronto dei riferimenti agli oggetti , mentre il metodo String .equals () della classe String viene sostituito per il 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)

40

Tutti gli oggetti hanno un .equals()metodo garantito poiché Object contiene un metodo .equals(), che restituisce un valore booleano. È compito della sottoclasse sostituire questo metodo se è necessaria un'ulteriore definizione di definizione. Senza di essa (cioè utilizzando ==) solo gli indirizzi di memoria vengono controllati tra due oggetti per l'uguaglianza. String sostituisce questo.equals() metodo e invece di utilizzare 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 grumi, quindi una volta creata una stringa viene sempre memorizzata in un programma allo stesso indirizzo. Le stringhe non cambiano, sono immutabili. Questo è il motivo per cui è una cattiva idea usare la concatenazione di stringhe regolare se si ha una grande quantità di elaborazione delle stringhe da fare. Invece useresti le StringBuilderclassi fornite. Ricorda che i puntatori a questa stringa possono cambiare e se tu fossi interessato a vedere se due puntatori erano uguali ==sarebbe una buona strada da percorrere. Le stringhe stesse no.


2
"una volta creata, una stringa viene memorizzata per sempre in un programma allo stesso indirizzo" - Questo è assolutamente sbagliato. Solo le espressioni di stringa costanti in fase di compilazione (possibilmente che coinvolgono final Stringvariabili) e le stringhe che il tuo programma internamente esplicitamente sono memorizzati in quello che tu chiami un "lump pool". Tutti gli altri Stringoggetti sono soggetti alla garbage collection quando non vi sono più riferimenti attivi ad essi, proprio come qualsiasi altro tipo di oggetto. Inoltre, mentre l'immutabilità è necessaria per il funzionamento dell'intero meccanismo di interning, è altrimenti irrilevante per questo.
Ted Hopp,

Il confronto delle stringhe viene eseguito tramite il metodo equals o equalsIgnoreCase che confronta effettivamente il contenuto della stringa. Ma il segno == controlla solo i valori di riferimento. Per i letterali di stringhe dal pool di stringhe funzionerà bene in questo caso. String s1 = new String ("a"); String s2 = new String ("a"); in questo caso s1 == s2 è falso, ma s1.equals (s2) è vero.
Shailendra Singh,

39

Puoi anche usare il compareTo()metodo per confrontare due stringhe. Se il risultato compareTo è 0, allora 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 tutte le stringhe utilizzando new String(somestring).intern(), puoi utilizzare l' ==operatore per confrontare due stringhe, altrimenti i metodi equals () o compareTo possono essere utilizzati solo.


35

In Java, quando l' operatore "==" viene utilizzato per confrontare 2 oggetti, verifica se gli oggetti si riferiscono allo stesso posto in memoria. In altre parole, controlla se i 2 nomi di oggetti sono sostanzialmente riferimenti alla stessa posizione di memoria.

La classe String Java sovrascrive effettivamente l'implementazione equals () predefinita 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 si chiama il metodo equals () per confrontare 2 oggetti String, quindi finché la sequenza effettiva di caratteri è uguale, entrambi gli oggetti vengono considerati uguali.

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

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


1
a meno che uno di questi sia nullo, poiché s.equals (s2) andrà in crash se s è nullo, causando il fallimento del confronto. Naturalmente, questo non contraddice davvero la risposta; è solo un avvertimento.
Jon Coombs,

1
No, non si arresterà in modo anomalo, genererà una NullPointerException, impedendo il confronto.
Bludzee,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.