- 1 1. Introduzione
- 2 2. Le basi delle stringhe in Java
- 3 3. Metodi di confronto delle stringhe
- 4 4. Esempi pratici di utilizzo
- 5 5. Prestazioni e ottimizzazione
- 6 6. Domande frequenti (FAQ)
- 6.1 Q1. Qual è la differenza tra == e equals()?
- 6.2 Q2. Perché l’uso di equals() può generare errori a causa di null?
- 6.3 Q3. Come confrontare ignorando maiuscole e minuscole?
- 6.4 Q4. Se vuoi confrontare le stringhe in base all’ordine di ordinamento?
- 6.5 Q5. Quali sono le best practice da ricordare per il confronto di stringhe?
- 7 7. Riepilogo
1. Introduzione
Qual è l’importanza del confronto delle stringhe in Java?
Nella programmazione Java, le occasioni in cui si gestiscono stringhe (String) sono numerose. Controlli di nomi utente, corrispondenza di valori di input da form, verifica di risposte API e così via: in ogni situazione è richiesto il confronto di stringhe.
In questi casi, “come confrontare correttamente le stringhe” è un punto in cui i principianti tendono a inciampare in modo inaspettato. In particolare, se non si comprende la differenza tra l’operatore == e il metodo equals(), può causare bug con risultati non intenzionali.
È pericoloso non capire la differenza tra “==” e “equals”
Ad esempio, guardate il seguente codice.
String a = "apple";
String b = new String("apple");
System.out.println(a == b); // 結果: false
System.out.println(a.equals(b)); // 結果: true
Molti rimarranno sorpresi dal risultato di output di questo codice. Anche se sono la stessa stringa, == restituisce false, mentre equals() restituisce true. Questo accade perché Java tratta le stringhe come “tipo di riferimento”, e == confronta gli indirizzi di riferimento.
In questo modo, confrontare correttamente le stringhe è direttamente collegato all’affidabilità e alla leggibilità del programma. Al contrario, comprendere il metodo corretto permette di prevenire bug in anticipo.
Cosa si può imparare in questo articolo
In questo articolo, spiegheremo in dettaglio i metodi di confronto delle stringhe in Java, dalla base all’avanzato. Risponderemo a domande come le seguenti, spiegando in modo strutturato e comprensibile anche per i principianti.
- Qual è la differenza tra
==eequals()? - Come confrontare ignorando maiuscole e minuscole?
- Come confrontare le stringhe in ordine lessicografico?
- Come evitare eccezioni nel confronto con null?
Attraverso esempi di codice utili nella pratica, acquisiremo solidamente la conoscenza corretta del confronto delle stringhe.
2. Le basi delle stringhe in Java
Le stringhe sono un “tipo di riferimento”
In Java, il tipo String non è un tipo primitivo (come int o boolean), ma un “tipo di riferimento (Reference Type)”. Questo significa che la variabile String non contiene i dati della stringa effettivi, ma riferisce a un oggetto stringa esistente nella memoria heap.
Quindi, se si scrive in questo modo:
String a = "hello";
String b = "hello";
a e b riferiscono alla stessa stringa "hello", quindi a == b potrebbe restituire true. Tuttavia, questo è dovuto al meccanismo di ottimizzazione dei letterali stringa (String Interning) di Java.
La differenza tra letterali stringa e new String()
In Java, se si utilizza lo stesso letterale stringa più volte, vengono ottimizzati come lo stesso riferimento. Questo è una funzionalità di Java per condividere le stringhe a runtime e migliorare l’efficienza della memoria.
String s1 = "apple";
String s2 = "apple";
System.out.println(s1 == s2); // true(同じリテラルなので同一参照)
D’altra parte, utilizzando la parola chiave new per generare esplicitamente un oggetto, si crea un nuovo riferimento.
String s3 = new String("apple");
System.out.println(s1 == s3); // false(異なる参照)
System.out.println(s1.equals(s3)); // true(内容は同じ)
In questo modo, == verifica la corrispondenza del riferimento, mentre equals() verifica la corrispondenza del contenuto, quindi i loro usi sono molto diversi.
String è una classe “immutabile”
Un’altra caratteristica importante è che String è immutabile (immutable). Cioè, il contenuto di un oggetto String una volta creato non può essere modificato.
Ad esempio, se si scrive in questo modo:
String original = "hello";
original = original + " world";
Sembra che si stia aggiungendo una stringa all’originale original, ma in realtà viene generato un nuovo oggetto String e assegnato a original.
Grazie a questa immutabilità, String è thread-safe e utile per la sicurezza e l’ottimizzazione della cache.
3. Metodi di confronto delle stringhe
Confronto di riferimenti con l’operatore ==
== confronta i riferimenti (indirizzi) degli oggetti stringa. Quindi, anche se il contenuto è lo stesso, se sono oggetti diversi, restituisce false.
String a = "Java";
String b = new String("Java");
System.out.println(a == b); // false
In questo esempio, a è un letterale e b è generato con new, quindi i riferimenti sono diversi e restituisce false. Non è adatto per il confronto del contenuto, quindi fate attenzione.
Confronto del contenuto con il metodo equals()
equals() è il metodo corretto per confrontare il contenuto delle stringhe. È raccomandato utilizzarlo in molte situazioni.
String a = "Java";
String b = new String("Java");
System.out.println(a.equals(b)); // true
In questo modo, anche se i riferimenti sono diversi, se il contenuto è lo stesso, restituisce true.
Punti di attenzione nel confronto con null
Il seguente codice può causare NullPointerException.
String input = null;
System.out.println(input.equals("test")); // 例外発生!
Per evitarlo, è raccomandato scrivere nel formato costante.equals(variabile).
System.out.println("test".equals(input)); // false(安全)
Confronto ignorando maiuscole e minuscole con il metodo equalsIgnoreCase()
Per nomi utente o indirizzi email, dove non si vuole distinguere tra maiuscole e minuscole, equalsIgnoreCase() è comodo.
String a = "Hello";
String b = "hello";
System.out.println(a.equalsIgnoreCase(b)); // true
Tuttavia, in alcuni casi speciali Unicode (come la “İ” in turco), potrebbe comportarsi in modo inaspettato, quindi per l’internazionalizzazione sono necessarie considerazioni aggiuntive.
Confronto lessicografico con il metodo compareTo()
compareTo() confronta due stringhe in ordine lessicografico e restituisce un intero come segue.
- 0: uguali
- Valore negativo: la stringa del chiamante è prima (più piccola)
- Valore positivo: la stringa del chiamante è dopo (più grande)
String a = "apple"; String b = "banana"; System.out.println(a.compareTo(b)); // 負の値("apple"は"banana"より前)
È spesso utilizzato per l’ordinamento lessicografico o il filtraggio, e internamente in Collections.sort() o nel confronto delle chiavi di TreeMap.
4. Esempi pratici di utilizzo
Verifica dell’input utente (funzione di login)
Una delle situazioni più comuni è la verifica della corrispondenza di nomi utente o password.
String inputUsername = "Naohiro";
String registeredUsername = "naohiro";
if (registeredUsername.equalsIgnoreCase(inputUsername)) {
System.out.println("ログイン成功");
} else {
System.out.println("ユーザー名が一致しません");
}
.Come mostrato in questo esempio, quando si desidera confrontare ignorando maiuscole e minuscole è opportuno usare equalsIgnoreCase().
Tuttavia, per motivi di sicurezza, i confronti di password dovrebbero distinguere tra maiuscole e minuscole, quindi usate equals().

Validazione dell’input (elaborazione dei form)
Ad esempio, il controllo dei valori inseriti da menu a discesa o caselle di testo utilizza il confronto di stringhe.
String selectedOption = request.getParameter("plan");
if ("premium".equals(selectedOption)) {
System.out.println("プレミアムプランを選択しました。");
} else {
System.out.println("その他のプランです。");
}
In questo modo, come confronto sicuro che include il controllo null, la forma "costante".equals(variazione) è comunemente usata in pratica. Poiché l’input dell’utente non è garantito, questo modo di scrivere previene NullPointerException.
Gestione di più condizioni (uso simile a switch)
Quando si desidera gestire più possibili stringhe in un ramo condizionale, è comune usare equals() in sequenza.
String cmd = args[0];
if ("start".equals(cmd)) {
startApp();
} else if ("stop".equals(cmd)) {
stopApp();
} else {
System.out.println("コマンドが不正です");
}
A partire da Java 14, è possibile utilizzare ufficialmente la dichiarazione switch con le stringhe.
switch (cmd) {
case "start":
startApp();
break;
case "stop":
stopApp();
break;
default:
System.out.println("不明なコマンドです");
}
Come si vede, il confronto di stringhe è direttamente collegato alla logica di ramificazione, quindi è necessaria una comprensione accurata.
Bug causati dal confronto con null e relative contromisure
Un errore comune è che l’applicazione si blocca quando si confronta con un valore null.
String keyword = null;
if (keyword.equals("検索")) {
// 例外発生:java.lang.NullPointerException
}
In questi casi, è possibile confrontare in modo sicuro scrivendo come segue.
if ("検索".equals(keyword)) {
System.out.println("検索実行");
}
Oppure, è possibile effettuare prima un controllo null più rigoroso.
if (keyword != null && keyword.equals("検索")) {
System.out.println("検索実行");
}
Il codice sicuro rispetto a null è una competenza indispensabile per aumentare la robustezza.
5. Prestazioni e ottimizzazione
Costo di elaborazione nel confronto di stringhe
equals() e compareTo() sono generalmente ottimizzati per funzionare velocemente, ma poiché confrontano carattere per carattere, possono avere un impatto quando si gestiscono stringhe lunghe o grandi quantità di dati. In particolare, confrontare ripetutamente la stessa stringa all’interno di un ciclo può causare un degrado delle prestazioni non previsto.
for (String item : items) {
if (item.equals("keyword")) {
// 比較回数が多い場合、注意
}
}
Accelerare il confronto con String.intern()
Utilizzando il metodo String.intern() di Java, è possibile registrare le stringhe con lo stesso contenuto nel “pool di stringhe” della JVM e condividere i riferimenti. Questo permette anche di confrontare con ==, offrendo potenziali vantaggi di prestazioni.
String a = new String("hello").intern();
String b = "hello";
System.out.println(a == b); // true
Tuttavia, un uso eccessivo del pool di stringhe può comprimere l’area heap, quindi dovrebbe essere limitato a casi d’uso specifici.
Trappole di equalsIgnoreCase() e alternative
equalsIgnoreCase() è comodo, ma poiché converte maiuscole e minuscole durante il confronto, può avere un costo leggermente superiore rispetto a equals() standard. In scenari con requisiti di prestazioni severi, è più veloce confrontare valori già uniformati in maiuscolo o minuscolo.
String input = userInput.toLowerCase();
if ("admin".equals(input)) {
// 高速化された比較
}
Come mostrato, convertire in anticipo e poi usare equals() migliora l’efficienza del confronto.
Utilizzo di StringBuilder / StringBuffer
Nei casi in cui si concatenano molte stringhe, l’uso di String genera un nuovo oggetto ad ogni operazione, aumentando il carico su memoria e CPU. Anche quando il confronto è coinvolto, la migliore pratica è usare StringBuilder per la concatenazione e la costruzione, mantenendo le stringhe per il confronto come String.
StringBuilder sb = new StringBuilder();
sb.append("user_");
sb.append("123");
String result = sb.toString();
if (result.equals("user_123")) {
// 比較処理
}
Progettazione per velocizzare con cache e pre-elaborazione
Quando lo stesso confronto di stringa avviene più volte, è efficace memorizzare il risultato del confronto in cache o pre-elaborare usando una mappa (come HashMap) per ridurre il numero di confronti.
Map<String, Runnable> commandMap = new HashMap<>();
commandMap.put("start", () -> startApp());
commandMap.put("stop", () -> stopApp());
Runnable action = commandMap.get(inputCommand);
if (action != null) {
action.run();
}
In questo modo, il confronto di stringhe con equals() viene sostituito da una singola ricerca nella mappa, migliorando sia la leggibilità che le prestazioni.
6. Domande frequenti (FAQ)
Q1. Qual è la differenza tra == e equals()?
A. == esegue un confronto di riferimento (cioè verifica se gli indirizzi di memoria coincidono). equals(), invece, confronta il contenuto della stringa.
String a = new String("abc");
String b = "abc";
System.out.println(a == b); // false(参照が異なる)
System.out.println(a.equals(b)); // true(内容は同じ)
Quindi, quando si desidera confrontare il contenuto di una stringa, usate sempre equals().
Q2. Perché l’uso di equals() può generare errori a causa di null?
A. Chiamare un metodo su null genera una NullPointerException.
String input = null;
System.out.println(input.equals("test")); // 例外発生!
Per evitare questo errore, è sicuro scrivere il confronto partendo dalla costante, come segue.
System.out.println("test".equals(input)); // false(安全)
Q3. Come confrontare ignorando maiuscole e minuscole?
.A.
Usando il metodo equalsIgnoreCase() è possibile confrontare ignorando le differenze tra maiuscole e minuscole.
String a = "Hello";
String b = "hello";
System.out.println(a.equalsIgnoreCase(b)); // true
Tuttavia, con caratteri a larghezza intera o alcuni caratteri Unicode speciali, il risultato può essere inatteso, quindi è necessario fare attenzione.
Q4. Se vuoi confrontare le stringhe in base all’ordine di ordinamento?
A.
Quando vuoi verificare la relazione di ordine lessicografico di una stringa, usa compareTo().
String a = "apple";
String b = "banana";
System.out.println(a.compareTo(b)); // 負の値("apple"は"banana"より前)
Significato del valore di ritorno:
- 0 → uguale
- valore negativo → la stringa a sinistra è prima
- valore positivo → la stringa a sinistra è dopo
Viene utilizzato in operazioni di ordinamento, ecc.
Q5. Quali sono le best practice da ricordare per il confronto di stringhe?
A.
- Confronto del contenuto: usa sempre
equals() - Sicurezza null: usa la forma
"costante".equals(variaibile) - Ignorare maiuscole/minuscole: usa
equalsIgnoreCase()o converti prima contoLowerCase()/toUpperCase() - Situazioni con molti confronti o necessità di velocità: considera
intern()o una progettazione di cache - Equilibrio tra leggibilità e sicurezza: tienilo sempre presente
7. Riepilogo
In Java, è importante “usare correttamente” i confronti di stringhe
In questo articolo abbiamo spiegato in modo completo le basi, le pratiche e le considerazioni di performance del confronto di stringhe in Java. Poiché String è un tipo di riferimento, un uso errato del metodo di confronto può portare a comportamenti inattesi.
In particolare, la differenza tra == e equals() è un punto che confonde spesso i principianti. Capirla correttamente e usarla in modo appropriato è fondamentale per scrivere codice sicuro e affidabile.
Cosa hai imparato da questo articolo (checklist)
==è un operatore che confronta i riferimenti (indirizzi di memoria)equals()è il metodo che confronta il contenuto della stringa (il più sicuro)- Usando
equalsIgnoreCase()è possibile ignorare maiuscole/minuscole - Con
compareTo()è possibile confrontare l’ordine lessicografico delle stringhe - Con l’ordine
"costante".equals(variaibile)è possibile confrontare in modo null‑safe - Se si considera la performance,
intern()o una progettazione di cache sono utili
Conoscenze sul confronto di stringhe utili anche in ambito professionale
Il confronto di stringhe è un elemento strettamente legato alle attività di sviluppo quotidiane, come la verifica di login, la validazione degli input, le ricerche nel database e le condizioni di flusso. Conoscere questi aspetti permette di prevenire bug e garantire che il codice si comporti come previsto.
In futuro, quando scriverai codice che gestisce stringhe, ti consigliamo di fare riferimento a questo articolo e scegliere il metodo di confronto più adatto allo scopo.


