Come invertire una stringa in Java
Inverti una stringa Java con StringBuilder.reverse, array di caratteri, ricorsione o stream.
Invertire una stringa significa produrre una nuova stringa i cui caratteri appaiono nell'ordine opposto — "Hello" diventa "olleH". Poiché le stringhe Java sono immutabili, non si può mai invertire una stringa in place; bisogna sempre costruirne una nuova. Esistono diversi modi idiomatici per farlo, e la scelta giusta dipende dal fatto che si voglia il codice più breve, il minor numero di dipendenze o la gestione corretta dei caratteri al di fuori del piano multilingue di base (come le emoji).
Questa pagina illustra quattro approcci — il metodo integrato StringBuilder.reverse, un ciclo manuale su un array di caratteri, la ricorsione e una pipeline di stream — li confronta in una tabella, poi esegue tutti e quattro sullo stesso input più due casi limite, così puoi vedere esattamente come si comportano.
Il modo idiomatico: StringBuilder.reverse
La libreria standard dispone già di un metodo reverse su StringBuilder (e StringBuffer). È la risposta in quasi ogni situazione:
String reversed = new StringBuilder("Hello").reverse().toString();
// reversed = "olleH"Racchiudi la stringa originale in un StringBuilder, chiama reverse() e poi toString() per ottenere una String normale. È veloce (un singolo passaggio, senza boxing) e si legge chiaramente. Un ulteriore vantaggio: StringBuilder.reverse() è surrogate-aware — mantiene insieme i due char di un code point supplementare (come un'emoji) invece di invertirli e produrre caratteri corrotti.
Ciclo manuale su un array di char
Quando si vogliono vedere i meccanismi interni — o ci si trova in un ambiente in cui non è possibile usare StringBuilder — si scorre un char[] dall'ultimo indice fino al primo:
char[] chars = "Hello".toCharArray();
StringBuilder out = new StringBuilder();
for (int i = chars.length - 1; i >= 0; i--) {
out.append(chars[i]);
}
String reversed = out.toString();Questo è esattamente ciò che fa internamente StringBuilder.reverse, senza la gestione dei surrogati. Evita di costruire il risultato con reversed += chars[i] su una String semplice: la concatenazione di stringhe in un ciclo crea un nuovo oggetto a ogni iterazione e trasforma un'operazione O(n) in O(n²).
Ricorsione e stream
Una soluzione ricorsiva si legge come la sua definizione — l'inverso di una stringa è l'inverso della sua coda seguito dal suo primo carattere:
static String reverse(String s) {
if (s.isEmpty()) return s;
return reverse(s.substring(1)) + s.charAt(0);
}È elegante, ma alloca una sottostringa per ogni chiamata e può causare un overflow dello stack su input molto lunghi, quindi trattala come uno strumento didattico piuttosto che codice di produzione. Una soluzione in una riga basata su stream evita la ricorsione ma è la meno leggibile di tutte:
String reversed = "Hello".chars()
.mapToObj(c -> String.valueOf((char) c))
.reduce("", (a, b) -> b + a);| Approccio | Righe | Velocità | Sicuro per i surrogati |
|---|---|---|---|
StringBuilder.reverse | 1 | Veloce | Sì |
| Ciclo manuale su char array | ~5 | Veloce | No |
| Ricorsione | ~4 | Lento, limitato dallo stack | No |
| Stream + reduce | ~3 | Lento (ricostruisce la stringa) | No |
Un esempio pratico
Questo programma inverte "Hello" in quattro modi diversi, conferma che tutti concordano, poi verifica due casi limite: una stringa vuota e una stringa contenente un'emoji (una coppia di surrogati).
Cosa osservare dall'esecuzione:
- Tutti e quattro gli approcci stampano
olleH, quindi sono intercambiabili per testo ASCII semplice — la scelta tra loro riguarda la leggibilità e le prestazioni, non la correttezza. StringBuilder.reverseha prodotto il risultato in un'unica espressione, ed è per questo che è la raccomandazione predefinita rispetto al ciclo, alla ricorsione e alle varianti con stream.- Invertire la stringa vuota restituisce la stringa vuota (
''), confermando che i metodi sono sicuri da chiamare senza un controllo della lunghezza — nessun caso speciale necessario. - Il
reversericorsivo si è concluso perché il suo caso base (s.isEmpty()) interrompe la catena di chiamate asubstring(1); senza quel controllo non avrebbe mai restituito un risultato. naive emoji ok: truemostra cheStringBuilder.reverseha mantenuto intatta l'emoji con la faccina sorridente — ha spostato la coppia di surrogati come un'unità. Un ciclochar-per-charscritto a mano avrebbe separato quella coppia e corrotto l'emoji.
Pratica
Argomenti correlati
- Metodi delle stringhe Java — il kit completo per suddividere, cercare e trasformare le stringhe.
- Java StringBuilder — il buffer mutabile alla base di
reverse()e della costruzione efficiente di stringhe. - Immutabilità delle stringhe — perché una
Stringnon può mai essere modificata in place.