Stringa vs StringBuffer vs StringBuilder

String è una delle classi più ampiamente utilizzate in Java. Le classi StringBuffer e StringBuilder forniscono metodi per manipolare le stringhe. Esamineremo la differenza tra StringBuffer e StringBuilder. StringBuffer vs StringBuilder è una domanda popolare nei colloqui Java.

Stringa vs StringBuffer vs StringBuilder

La stringa è uno degli argomenti più importanti nei colloqui di base di Java. Se stai scrivendo un programma che stampa qualcosa sulla console, utilizzi la Stringa. Questo tutorial mira a concentrarsi sulle principali caratteristiche della classe Stringa. Successivamente, confrontiamo le classi StringBuffer e StringBuilder.

Stringa in Java

  1. La classe Stringa rappresenta stringhe di caratteri, possiamo istanziare la Stringa in due modi.

    Stringa str = "ABC";
    // o 
    Stringa str = new String("ABC");
    
  2. La Stringa è immutabile in Java. Quindi è adatta all’uso in un ambiente multithreading. Possiamo condividerla tra le funzioni senza preoccuparci di inconsistenze nei dati.

  3. Quando creiamo una stringa usando virgolette doppie, il JVM cerca prima la stringa con lo stesso valore nel pool delle stringhe. Se viene trovata, restituisce il riferimento dell’oggetto stringa dal pool. Altrimenti, crea l’oggetto String nel pool delle stringhe e restituisce il riferimento. Il JVM risparmia molta memoria utilizzando la stessa stringa in thread diversi.

  4. Se viene utilizzato l’operatore new per creare una stringa, viene creata nella memoria heap.

  5. L’operatore + è sovraccaricato per la Stringa. Possiamo usarlo per concatenare due stringhe. Anche se internamente utilizza StringBuffer per eseguire questa operazione.

  6. String sovrascrive i metodi equals() e hashCode(). Due String sono uguali solo se hanno la stessa sequenza di caratteri. Il metodo equals() fa distinzione tra maiuscole e minuscole. Se stai cercando controlli non sensibili alle maiuscole, dovresti usare il metodo equalsIgnoreCase().

  7. La stringa utilizza la codifica UTF-16 per il flusso di caratteri.

  8. String è una classe finale. Tutti i campi sono final tranne “private int hash”. Questo campo contiene il valore della funzione hashCode(). Il valore di hash viene calcolato solo quando viene chiamato il metodo hashCode() per la prima volta e quindi memorizzato nella cache in questo campo. Inoltre, l’hash viene generato utilizzando i campi final della classe String con alcuni calcoli. Quindi ogni volta che viene chiamato il metodo hashCode(), si otterrà lo stesso output. Per chi chiama il metodo, sembra che i calcoli vengano eseguiti ogni volta, ma internamente è memorizzato nella cache nel campo hash.

String è una classe finale. Tutti i campi sono final tranne “private int hash”. Questo campo contiene il valore della funzione hashCode(). Il valore di hashcode viene calcolato solo quando il metodo hashCode() viene chiamato per la prima volta e poi memorizzato nella cache in questo campo. Inoltre, l’hash è generato utilizzando i campi finali della classe String con alcuni calcoli. Quindi ogni volta che il metodo hashCode() viene chiamato, si ottiene lo stesso risultato. Per il chiamante, sembra che i calcoli avvengano ogni volta, ma internamente è memorizzato nella cache nel campo hash.

Poiché String è immutabile in Java, ogni volta che facciamo manipolazioni di String come concatenazione, substring, ecc., viene generata una nuova String e scartata la vecchia String per la raccolta di rifiuti. Queste sono operazioni pesanti e generano molta spazzatura nell’heap. Quindi Java ha fornito le classi StringBuffer e StringBuilder che dovrebbero essere utilizzate per la manipolazione delle Stringhe. StringBuffer e StringBuilder sono oggetti mutabili in Java. Forniscono metodi come append(), insert(), delete(), e substring() per la manipolazione delle Stringhe.

StringBuffer vs StringBuilder

StringBuffer era l’unica scelta per la manipolazione delle stringhe fino a Java 1.4. Tuttavia, ha un inconveniente: tutti i suoi metodi pubblici sono sincronizzati. StringBuffer fornisce sicurezza del thread ma a un costo in termini di prestazioni. Nella maggior parte degli scenari, non utilizziamo le stringhe in un ambiente multithread. Perciò, Java 1.5 ha introdotto una nuova classe StringBuilder, simile a StringBuffer ad eccezione della sicurezza del thread e della sincronizzazione. StringBuffer ha alcuni metodi aggiuntivi come substring, length, capacity, trimToSize, ecc. Tuttavia, questi non sono necessari poiché sono già presenti anche in String. Ecco perché questi metodi non sono mai stati implementati nella classe StringBuilder. StringBuffer è stata introdotta in Java 1.0, mentre la classe StringBuilder è stata introdotta in Java 1.5 dopo aver esaminato le limitazioni di StringBuffer. Se ti trovi in un ambiente con un singolo thread o non ti interessa la sicurezza del thread, dovresti utilizzare StringBuilder. Altrimenti, utilizza StringBuffer per operazioni thread-safe.

Performance di StringBuilder vs StringBuffer

I am trying to check the effect on performance because of synchronization with a sample program that performs append() on StringBuffer and StringBuilder object for multiple times.

package com.journaldev.java;

import java.util.GregorianCalendar;

public class TestString {

	public static void main(String[] args) {
		System.gc();
		long start=new GregorianCalendar().getTimeInMillis();
		long startMemory=Runtime.getRuntime().freeMemory();
		StringBuffer sb = new StringBuffer();
		//StringBuilder sb = new StringBuilder();
		for(int i = 0; i<10000000; i++){
			sb.append(":").append(i);
		}
		long end=new GregorianCalendar().getTimeInMillis();
		long endMemory=Runtime.getRuntime().freeMemory();
		System.out.println("Time Taken:"+(end-start));
		System.out.println("Memory used:"+(startMemory-endMemory));
	}
}

I ran the same code for the StringBuffer object also to check the time and memory values. I have executed the code 5 times for each case and then calculated the average values.

Value of i StringBuffer (Time, Memory) StringBuilder (Time, Memory)
10,00,000 808, 149356704 633, 149356704
1,00,00,000 7448, 147783888 6179, 147783888

È evidente che StringBuilder ha prestazioni migliori rispetto a StringBuffer anche in caso di ambiente con un singolo thread. Questa differenza di prestazioni può essere causata dalla sincronizzazione nei metodi di StringBuffer.

Stringa vs StringBuffer vs StringBuilder

  1. La stringa è immutabile, mentre StringBuffer e StringBuilder sono classi mutabili.
  2. StringBuffer è thread-safe e sincronizzato, mentre StringBuilder non lo è. Ecco perché StringBuilder è più veloce di StringBuffer.
  3. L’operatore di concatenazione delle stringhe (+) utilizza internamente la classe StringBuffer o StringBuilder.
  4. Per le manipolazioni delle stringhe in un ambiente non multi-thread, dovremmo utilizzare StringBuilder, altrimenti utilizzare la classe StringBuffer.

Questo è tutto per una rapida panoramica delle differenze tra String, StringBuffer e StringBuilder. StringBuilder è più adatto di StringBuffer nella maggior parte degli scenari di programmazione generale. Riferimenti:

Source:
https://www.digitalocean.com/community/tutorials/string-vs-stringbuffer-vs-stringbuilder