W3docs

Come Confrontare Stringhe in Java

Confronta stringhe Java con equals, equalsIgnoreCase, compareTo ed evita l'errore classico con ==.

Confrontare due valori String in Java è una delle prime cose che un principiante sbaglia, perché l'operatore == confronta silenziosamente i riferimenti invece dei contenuti. Questo capitolo mostra i modi corretti e idiomatici per verificare l'uguaglianza e l'ordinamento delle stringhe — equals, equalsIgnoreCase, compareTo e il null-safe Objects.equals — e spiega esattamente quando ognuno è lo strumento giusto.

Per la ragione sottostante per cui letterali identici possono essere ==, consulta il string pool; per un'analisi più ampia delle tecniche di confronto, consulta il confronto di stringhe in Java.

Uguaglianza dei contenuti con equals

Per verificare se due stringhe contengono gli stessi caratteri, utilizza equals:

String a = "hello";
String b = new String("hello");

boolean same = a.equals(b);   // true — same characters

equals scorre le due sequenze di caratteri e restituisce true solo quando hanno la stessa lunghezza e gli stessi caratteri nello stesso ordine. È il metodo che vuoi nel 99% delle volte in cui chiedi "queste due stringhe sono lo stesso testo?".

Un trucco difensivo comune è chiamare equals su un letterale stringa in modo che il ricevitore non sia mai null:

if ("yes".equals(userInput)) { ... }   // safe even if userInput is null

Perché == è la trappola classica

== non guarda affatto i caratteri — chiede "sono esattamente lo stesso oggetto in memoria?". Poiché il compilatore interna i letterali stringa (memorizza una copia condivisa in un pool), due letterali identici possono risultare ==, il che induce le persone a pensare che == confronti il testo. Non è così: nel momento in cui una stringa proviene da new, dall'input dell'utente o dalla concatenazione a runtime, == restituisce false anche per testo identico.

EspressioneRisultatoMotivo
"java" == "java"trueEntrambi fanno riferimento allo stesso letterale internato
"java" == new String("java")falsenew crea un oggetto distinto
"java".equals(new String("java"))trueConfronta i contenuti, non l'identità

Regola pratica: non usare mai == per confrontare stringhe. Usa equals.

Confronto senza distinzione tra maiuscole e minuscole con equalsIgnoreCase

Quando le maiuscole/minuscole non devono essere rilevanti — nomi utente, estensioni di file, nomi di intestazioni — usa equalsIgnoreCase:

"Java".equalsIgnoreCase("JAVA");   // true

Applica la stessa logica carattere per carattere di equals dopo aver uniformato il caso, quindi "README".equalsIgnoreCase("readme") è true.

Ordinamento con compareTo

Per ordinare o classificare le stringhe anziché semplicemente testare l'uguaglianza, usa compareTo, che restituisce il segno della differenza lessicografica (ordine dizionario):

"apple".compareTo("banana");   // negative — apple comes first
"apple".compareTo("apple");    // 0       — equal
"banana".compareTo("apple");   // positive — banana comes later

Un risultato negativo significa che il ricevitore viene prima dell'argomento, 0 significa uguale, positivo significa dopo. Esiste una variante compareToIgnoreCase e String.CASE_INSENSITIVE_ORDER da usare come Comparator. Nota che l'ordinamento predefinito è per punto di codice Unicode, quindi tutte le lettere maiuscole (AZ) vengono prima di tutte le lettere minuscole.

Un esempio pratico

Questo programma mette in pratica ogni approccio fianco a fianco in modo da vedere esattamente come si comporta ciascuno.

java— editable, runs on the server

Cosa osservare dall'esecuzione:

  • a == b stampa false anche se entrambe le stringhe leggono "java", perché new String("java") è un oggetto separato — prova che == confronta l'identità, non il testo.
  • a.equals(b) stampa true: equals guarda i caratteri, che è quasi sempre ciò che si intende con "la stessa stringa".
  • a == c stampa true solo perché entrambi sono letterali che condividono un oggetto internato — questo successo accidentale è esattamente il motivo per cui == attira i principianti in un bug.
  • equalsIgnoreCase stampa true per "Java" vs "JAVA", mentre compareTo restituisce 0 per testo identico e un segno non zero (-1 per apple prima di banana) quando differiscono.
  • Objects.equals(null, "x") stampa false invece di lanciare un'eccezione, e l'array ordinato stampa [Cherry, apple, banana] — la C maiuscola (punto di codice 67) viene prima delle lettere minuscole (punto di codice 97+).

Quale metodo dovrei usare?

Scegli il confronto in base alla domanda a cui stai effettivamente rispondendo:

Vuoi sapere…UsaNote
Il testo è esattamente uguale?a.equals(b)La scelta predefinita per l'uguaglianza
Uguale, ignorando maiuscole/minuscole?a.equalsIgnoreCase(b)Uniforma il caso prima
Uguale, ma uno dei due potrebbe essere null?Objects.equals(a, b)Restituisce true per due null, non lancia mai eccezioni
Qual è il loro ordine di ordinamento?a.compareTo(b)Negativo / 0 / positivo
Ordine di ordinamento, ignorando il caso?a.compareToIgnoreCase(b)Oppure String.CASE_INSENSITIVE_ORDER come Comparator

Un'abitudine utile: quando hai bisogno solo dell'uguaglianza, preferisci equals (o Objects.equals quando null è possibile) e mai compareTo(...) == 0, che fa strettamente più lavoro. Per esplorare i metodi su cui si basano, consulta i metodi delle stringhe Java e la classe String.

Esercizio

Pratica
Perché l'espressione new String('hi') == 'hi' restituisce false in Java?
Perché l'espressione new String('hi') == 'hi' restituisce false in Java?
Was this page helpful?