Operazioni sulle Stringhe in Java

Poiché le stringhe sono una parte comune e importante della programmazione, Java ha aggiunto un supporto speciale per diverse operazioni sulle stringhe all'interno della sintassi del linguaggio.

Queste operazioni includono la creazione automatica di nuove istanze String dai letterali stringa, la concatenazione di più oggetti String mediante l'uso dell'operatore +, e la conversione di altri tipi di dati in una rappresentazione stringa.

Ci sono metodi espliciti disponibili per eseguire tutte queste funzioni, ma Java li esegue automaticamente come comodità per il programmatore e per aggiungere chiarezza.

Concetti Chiave
  • Java supporta alcune operazioni sulle stringhe come parte della sintassi del linguaggio.
  • Per ottenere la lunghezza di una stringa, si utilizza il metodo length().
  • Le stringhe possono essere create da letterali di stringa, che sono automaticamente convertiti in oggetti String.
  • L'operatore + può essere utilizzato per concatenare stringhe.
  • Le stringhe possono essere concatenate con altri tipi di dati, che vengono convertiti automaticamente in stringhe.
  • Il metodo valueOf() può essere utilizzato per convertire altri tipi di dati in stringhe.
  • Ogni classe può sovrascrivere il metodo toString() per fornire una rappresentazione stringa personalizzata degli oggetti di quella classe.

Lunghezza di una Stringa

La lunghezza di una stringa è il numero di caratteri che contiene.

Per ottenere questo valore, chiamiamo il metodo length(), mostrato qui:

int length()

Il seguente frammento di codice stampa "3", poiché ci sono tre caratteri nella stringa s:

char[] caratteri = { 'a', 'b', 'c' };
String s = new String(caratteri);
System.out.println(s.length());

Creazione di Stringhe a partire da Letterali di Stringa

Gli esempi nella lezione precedente hanno mostrato come creare esplicitamente un'istanza di String da un array di caratteri utilizzando l'operatore new.

Tuttavia, c'è un modo più semplice per farlo utilizzando un letterale di stringa. Per ogni letterale di stringa in un programma, Java costruisce automaticamente un oggetto String. Pertanto, si può utilizzare un letterale di stringa per inizializzare un oggetto String.

Ad esempio, il seguente frammento di codice crea due stringhe equivalenti:

char[] caratteri = { 'a', 'b', 'c' };

// Crea una stringa da un array di caratteri
String s1 = new String(caratteri);

// Crea una stringa da un array di caratteri
String s2 = "abc";

Poiché un oggetto String viene creato per ogni letterale di stringa, si può utilizzare un letterale di stringa ovunque si possa utilizzare un oggetto String.

Ad esempio, si possono chiamare metodi direttamente su una stringa quotata come se fosse un riferimento a oggetto, come mostra la seguente istruzione.

In questo esempio, viene invocato il metodo length() sulla stringa "abc". Come previsto, stampa "3".

System.out.println("abc".length());

Concatenazione di Stringhe

In generale, Java non consente l'applicazione di operatori agli oggetti String.

L'unica eccezione a questa regola è l'operatore +, che concatena due stringhe, producendo un oggetto String come risultato. Questo consente di concatenare una serie di operazioni +.

Ad esempio, il seguente frammento di codice concatena tre stringhe:

String eta = "9";
String s = "Lui ha " + eta + " anni.";
System.out.println(s);

Questo codice visualizza la stringa "Lui ha 9 anni."

Un uso pratico della concatenazione di stringhe si trova quando si creano stringhe molto lunghe.

Invece di lasciare che le stringhe lunghe si avviluppino all'interno del codice sorgente, è possibile suddividerle in pezzi più piccoli, utilizzando il + per concatenarle.

Ecco un esempio:

// Utilizzo della concatenazione per prevenire
// la scrittura di righe di codice lunghe.
class ConcatenazioneCat {

    public static void main(String[] args) {
        String stringaLunga = "Questa avrebbe potuto essere " +
                            "una riga molto lunga che si sarebbe " +
                            "avviluppata. Ma la concatenazione di stringhe " +
                            "previene questo.";
        System.out.println(stringaLunga);
    }

}

Concatenazione di Stringhe con Altri Tipi di Dati

Possiamo concatenare stringhe con altri tipi di dati.

Ad esempio, consideriamo questa versione leggermente diversa dell'esempio precedente:

int eta = 9;
String s = "Lui ha " + eta + " anni.";
System.out.println(s);

In questo caso, eta è un int piuttosto che un'altra String, ma l'output prodotto è lo stesso di prima.

Questo accade perché il valore int in eta viene automaticamente convertito nella sua rappresentazione stringa all'interno di un oggetto String. Questa stringa viene poi concatenata come prima. Il compilatore convertirà un operando nel suo equivalente stringa ogni volta che l'altro operando del + è un'istanza di String.

Tuttavia, bisogna fare attenzione quando si mescolano altri tipi di operazioni con espressioni di concatenazione di stringhe. Si potrebbero ottenere risultati sorprendenti.

Consideriamo il seguente frammento di codice:

String s = "quattro: " + 2 + 2;
System.out.println(s);

Questo frammento visualizza

quattro: 22

piuttosto che il risultato atteso:

quattro: 4

La motivazione sta nella precedenza degli operatori.

La precedenza degli operatori causa prima la concatenazione di "quattro" con l'equivalente stringa di 2. Questo risultato viene poi concatenato con l'equivalente stringa di 2 una seconda volta. Per completare prima l'addizione intera, bisogna usare le parentesi, in questo modo:

String s = "quattro: " + (2 + 2);

Ora s contiene la stringa "quattro: 4".

Conversione di Dati in Stringhe

Un modo per convertire i dati nella loro rappresentazione stringa consiste nell'invocare una delle versioni sovraccaricate del metodo di conversione stringa valueOf() definito da String.

valueOf() è sovraccaricato per tutti i tipi primitivi e per il tipo Object. Per i tipi primitivi, valueOf() restituisce una stringa che contiene l'equivalente leggibile del valore con cui viene chiamato. Per gli oggetti, valueOf() chiama il metodo toString() sull'oggetto. Esamineremo più da vicino valueOf() nelle prossime lezioni. Qui, esaminiamo il metodo toString(), perché è il mezzo attraverso il quale possiamo determinare la rappresentazione stringa per oggetti di classi che creiamo.

Ogni classe implementa toString() perché è definito da Object. Tuttavia, l'implementazione predefinita di toString() è raramente sufficiente. Per la maggior parte delle classi importanti che creiamo, vorremo sovrascrivere toString() e fornire le nostre rappresentazioni stringa. Fortunatamente, questo è facile da fare. Il metodo toString() ha questa forma generale:

String toString()

Per implementare toString(), restituiamo semplicemente un oggetto String che contiene la stringa leggibile che descrive appropriatamente un oggetto della nostra classe.

Sovrascrivendo toString() per le classi che creiamo, permettiamo loro di essere completamente integrate nell'ambiente di programmazione Java. Ad esempio, possono essere utilizzate nelle istruzioni print() e println() e nelle espressioni di concatenazione. Il seguente programma dimostra questo sovrascrivendo toString() per la classe Scatola:

// Sovrascrivere toString() per la classe Scatola.
class Scatola {

    double larghezza;
    double altezza;
    double profondita;

    Scatola(double l, double a, double p) {
        larghezza = l;
        altezza = a;
        profondita = p;
    }

    public String toString() {
        return "Le dimensioni sono " + larghezza + " per " +
        profondita + " per " + altezza + ".";
    }

}

class DemoToString {

    public static void main(String[] args) {
        Scatola s = new Scatola(10, 12, 14);

        // Concatena l'oggetto Scatola con una stringa.
        // Questa riga invoca automaticamente toString().
        String str = "Scatola s: " + s;

        // Stampa l'oggetto Scatola.
        // Questa riga invoca automaticamente toString().
        System.out.println(s);

        // Stampa la stringa concatenata.
        System.out.println(str);
    }

}

L'output di questo programma è mostrato qui:

Le dimensioni sono 10.0 per 14.0 per 12.0.
Scatola s: Le dimensioni sono 10.0 per 14.0 per 12.0.

Come possiamo vedere, il metodo toString() di Scatola viene automaticamente invocato quando un oggetto Scatola viene utilizzato in un'espressione di concatenazione o in una chiamata a println().