Come faccio a confrontare le stringhe in Java?

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

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

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

.equals() verifica l’uguaglianza dei valori (indipendentemente dal fatto che siano logicamente “uguali”).

Objects.equals () verifica null prima di chiamare .equals() modo da non doverlo (disponibile a partire da JDK7, disponibile anche in Guava ).

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

Di conseguenza, se vuoi verificare se due stringhe hanno lo stesso valore, 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 rara situazione in cui sai che hai a che fare con stringhe internate , puoi usare == .

Da JLS 3.10.5. Stringhe letterali :

Inoltre, una stringa letterale fa sempre riferimento alla stessa istanza della class String . Questo perché stringhe letterali – o, più in generale, stringhe che sono i valori delle espressioni costanti ( §15.28 ) – sono “internate” in modo da condividere istanze univoche, usando il metodo String.intern .

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

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

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

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 bene le stringhe null , ma chiamando .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 fooString1 potrebbe essere nullo, 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")); 

== confronta i riferimenti dell’object.

.equals() confronta i valori di stringa.

A volte == dà illusioni sul confronto dei valori di stringa, 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 letterale nel pool String e, se trova una corrispondenza, lo stesso riferimento verrà assegnato alla nuova stringa. Per questo motivo otteniamo:

(a == b) ===> true

  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 la new String("test") l'istruzione new String verrà creata sull'heap e tale riferimento verrà assegnato a b , quindi a b verrà assegnato un riferimento sull'heap, non nel pool di stringhe.

Ora a sta puntando a una stringa nel pool String mentre b sta puntando a una stringa sull'heap. Per questo otteniamo:

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

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

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

L’operatore == controlla se le due stringhe sono esattamente lo stesso object.

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

Le stringhe in Java sono immutabili. Ciò significa che ogni volta che provi a cambiare / modificare la stringa ottieni una nuova istanza. Non è ansible 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 alle stringhe e la memorizzazione nella cache di queste istanze può ridurre l’ingombro della 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 si sta effettivamente confrontando l’indirizzo di memoria. Se sono entrambi uguali, restituirà true e false altrimenti. Mentre è uguale alla stringa, confronta il contenuto della stringa.

Quindi la domanda è se tutte le stringhe sono memorizzate nella cache del sistema, come mai == restituisce false mentre equals restituisce true? Bene, questo è ansible. 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 false.

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

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

 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 aver capito perché. È perché il confronto == confronta solo i riferimenti; il metodo equals() esegue un confronto carattere per carattere dei contenuti.

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

Sì, è brutto …

== significa che i tuoi due riferimenti di stringa sono esattamente lo stesso object. Potresti aver sentito che questo è il caso perché Java mantiene una sorta di tabella letterale (che fa), ma non è sempre così. Alcune stringhe sono 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.

Sì, == è male per confrontare le stringhe (qualsiasi object in realtà, a meno che tu non sappia che sono canoniche). == confronta solo i riferimenti agli oggetti. .equals() verifica l’uguaglianza. Per le stringhe, spesso saranno uguali ma, come hai scoperto, non è sempre garantito.

Java ha un pool di stringhe in cui Java gestisce l’allocazione di memoria per gli oggetti String. Vedi Pool di stringhe in Java

Quando controlli (confronta) due oggetti usando l’operatore == , confronta l’uguaglianza di indirizzo nel pool di stringhe. Se i due oggetti String hanno gli stessi riferimenti di indirizzo, restituisce true , altrimenti false . Ma se si desidera confrontare il contenuto di due oggetti String, è necessario sovrascrivere il metodo equals .

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

 Example: stringObjectOne.equals(stringObjectTwo); 

Ma rispetta il caso di String. Se si desidera confrontare con maiuscole e minuscole, è necessario utilizzare il metodo equalsIgnoreCase della class 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 

.equals() confronta i dati in una class (assumendo che la funzione sia implementata). == confronta le posizioni del puntatore (posizione dell’object in memoria).

== restituisce true se entrambi gli oggetti (NOT TALKING ABOUT PRIMITIVES) puntano all’istanza dell’object SAME. .equals() restituisce true se i due oggetti contengono gli stessi dati equals() Versus == in Java

Questo potrebbe aiutarti.

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

Per confrontare i contenuti effettivi degli oggetti (compresa la String ), è necessario utilizzare il metodo equals .

Se un confronto tra due oggetti String usando == risulta true , cioè perché gli oggetti String sono internati e la Java Virtual Machine ha più riferimenti puntano alla stessa istanza di String . Non ci si dovrebbe aspettare che confrontando un object String contenente lo stesso contenuto di un altro object String usando == per valutare come true .

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

Il metodo equals() controlla se il contenuto o gli stati di 2 oggetti sono gli stessi.

Ovviamente == è più veloce, ma (potrebbe) fornire risultati falsi in molti casi se si vuole solo dire se 2 String s mantengono lo stesso testo.

Sicuramente si raccomanda l’uso del metodo equals() .

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

  1. L’implementazione di String.equals() controlla prima l’uguaglianza di riferimento (usando == ), e se le 2 stringhe sono le stesse per riferimento, non viene eseguito alcun ulteriore calcolo!
  2. Se i 2 riferimenti di stringa non sono gli stessi, String.equals() verificherà successivamente le lunghezze delle stringhe. Questa è anche un’operazione veloce perché la class String memorizza la lunghezza della stringa, senza bisogno di contare i caratteri oi punti di codice. Se le lunghezze differiscono, nessun ulteriore controllo viene eseguito, sappiamo che non possono essere uguali.
  3. Solo se siamo arrivati ​​così lontano, il contenuto delle 2 stringhe verrà effettivamente confrontato, e questo sarà un confronto a breve termine: non tutti i personaggi saranno confrontati, se troviamo un carattere non corrispondente (nella stessa posizione nelle 2 stringhe ), non verranno controllati ulteriori caratteri.

Quando tutto è stato detto e fatto, anche se abbiamo garantito che le stringhe sono stagisti, l’uso del metodo equals() non è ancora quel sovraccarico che si potrebbe pensare, decisamente il modo consigliato. Se si desidera un controllo di riferimento efficiente, utilizzare le enumerazioni in cui è garantito dalla specifica del linguaggio e dall’implementazione che lo stesso valore enumerato sarà lo stesso object (per riferimento).

Sono d’accordo con la risposta degli zacherati.

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

Dall’esempio zacherates:

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

Se si internamente l’uguaglianza di stringa non letterale è vera

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

Se sei come me, quando ho iniziato a usare Java, volevo usare l’operatore “==” per verificare se due istanze di 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, iniziando dall’approccio che uso la maggior parte del tempo. Alla fine di questo tutorial di confronto sulle stringhe di Java illustrerò anche perché l’operatore “==” non funziona quando si confrontano le stringhe Java.

Opzione 1: confronto delle stringhe Java con il metodo equals La maggior parte delle volte (forse il 95% delle volte) confronto le stringhe con il metodo equals della class Java String, in questo modo:

 if (string1.equals(string2)) 

Questo metodo di stringa uguale a due stringhe Java e se contengono esattamente la stessa stringa di caratteri, sono considerate uguali.

Prendendo in considerazione un rapido esempio di confronto delle stringhe con il metodo equals, se il test seguente è stato eseguito, le due stringhe non sarebbero considerate uguali perché i caratteri non sono esattamente uguali (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 comparazione delle stringhe vorrai ignorare se le stringhe sono maiuscole o minuscole. Quando vuoi testare le stringhe per l’uguaglianza in questo modo insensibile alle maiuscole e minuscole, usa il metodo equalsIgnoreCase della class 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

C’è anche un terzo modo, meno comune, di confrontare le stringhe Java, e questo è con il metodo compareTo della class String. Se le due stringhe sono esattamente uguali, il metodo compareTo restituirà un valore pari a 0 (zero). Ecco un rapido esempio di come si presenta questo approccio di confronto String:

 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 equals nella class Java Object di base. Ogni volta che crei i tuoi oggetti e vuoi fornire un mezzo per vedere se due istanze del tuo object sono “uguali”, devi sovrascrivere (e attuare) questo metodo uguali nella tua class (nello stesso modo in cui il linguaggio Java fornisce questo comportamento di uguaglianza / confronto nel metodo String equals).

Potresti dare un’occhiata a questo ==, .equals (), compareTo () e compare ()

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

L’operatore == controlla se i due riferimenti puntano allo stesso object o meno. .equals() controlla il contenuto della stringa effettiva (valore).

Si noti che il metodo .equals() appartiene alla class Object (super class di tutte le classi). Hai bisogno di sovrascriverlo secondo i tuoi requisiti di class, 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 stringa creati senza null vengono memorizzati nel lotto di stringhe nell’area permgen dell’heap. Quindi entrambi s1 e s2 puntano allo stesso object 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 object String utilizzando la new parola chiave, sullo heap viene allocato uno spazio separato.

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

Penso che quando definisci una String , definisci un object. Quindi devi usare .equals() . Quando usi tipi di dati primitivi usi == ma con String (e qualsiasi object) devi usare .equals() .

Se il metodo equals() è presente nella class java.lang.Object , è previsto che verifichi l’equivalenza dello stato degli oggetti! Ciò significa, il contenuto degli oggetti. Mentre l’operatore == dovrebbe verificare che le istanze dell’object reale siano uguali o meno.

Esempio

Prendi in considerazione due diverse variabili di riferimento, str1 e str2 :

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

Se usi gli equals()

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

Otterrai l’output come TRUE se usi == .

 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 stringhe. È a causa della new String() ogni volta viene creato un nuovo object.

L’operatore == è sempre inteso per il confronto dei riferimenti agli oggetti , mentre il metodo della class String .equals () viene sovrascritto 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) 

Tutti gli oggetti hanno un metodo .equals() poiché Object contiene un metodo, .equals() , che restituisce un valore booleano. È compito della sottoclass eseguire l’override di questo metodo se è necessaria un’ulteriore definizione. Senza di essa (cioè usando == ) solo gli indirizzi di memoria vengono controllati tra due oggetti per l’uguaglianza. La stringa 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 unico pool di dati, quindi una volta creata una stringa, questa viene memorizzata per sempre in un programma allo stesso indirizzo. Le stringhe non cambiano, sono immutabili. Questo è il motivo per cui è una ctriggers idea usare una normale concatenazione di stringhe se si ha una seria quantità di elaborazione di stringhe da fare. Invece dovresti usare le classi StringBuilder fornite. Ricorda che i puntatori a questa stringa possono cambiare e se ti interessava vedere se due puntatori erano uguali == sarebbe una buona strada da percorrere. Le stringhe stesse no.

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

Il == confronta i riferimenti e non confronta le stringhe reali. Se hai creato ogni stringa utilizzando la new String(somestring).intern() , puoi utilizzare l’operatore == per confrontare due stringhe, altrimenti equals () o compareTo i metodi possono essere utilizzati solo.

In Java, quando l’operatore “==” viene utilizzato per confrontare 2 oggetti, controlla se gli oggetti si riferiscono allo stesso posto in memoria. In altre parole, controlla se i 2 nomi object sono fondamentalmente riferimenti alla stessa posizione di memoria.

La class Java String sovrascrive l’implementazione default equals () nella class 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 sono considerati uguali.

L’operatore == controlla se le due stringhe sono esattamente lo stesso object.

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