String vs StringBuffer vs StringBuilder

String vs StringBuffer vs StringBuilder

String in Java

  1. A classe String representa cadeias de caracteres e pode ser instanciada de duas maneiras.

    String str = "ABC";
    // ou
    String str = new String("ABC");
    
  2. A String é imutável em Java, sendo adequada para uso em ambientes multi-threaded. Pode ser compartilhada entre funções sem preocupações com inconsistência de dados.

  3. Ao criar uma String usando aspas duplas, a JVM primeiro procura pela String com o mesmo valor no pool de strings. Se encontrada, ela retorna a referência do objeto de string do pool. Caso contrário, cria o objeto String no pool de strings e retorna a referência. A JVM economiza muita memória usando a mesma String em diferentes threads.

  4. Se o operador new for usado para criar uma string, ela será criada na memória heap.

  5. O operador + é sobrecarregado para String. Podemos usá-lo para concatenar duas strings. Embora internamente ele use StringBuffer para realizar essa ação.

  6. A classe String substitui os métodos equals() e hashCode(). Duas Strings são iguais apenas se tiverem a mesma sequência de caracteres. O método equals() diferencia maiúsculas de minúsculas. Se estiver procurando por verificações sem diferenciação de maiúsculas e minúsculas, deve usar o método equalsIgnoreCase().

  7. A string utiliza a codificação UTF-16 para a sequência de caracteres.

  8. A classe String é uma classe final. Todos os campos são finais, exceto “private int hash”. Este campo contém o valor da função hashCode(). O valor do hash é calculado apenas quando o método hashCode() é chamado pela primeira vez e depois é armazenado em cache neste campo. Além disso, o hash é gerado usando os campos finais da classe String com alguns cálculos. Portanto, cada vez que o método hashCode() é chamado, o resultado será o mesmo. Para o chamador, parece que os cálculos estão ocorrendo toda vez, mas internamente estão armazenados em cache no campo hash.

String vs StringBuffer

Como String é imutável em Java, sempre que fazemos manipulação de String, como concatenação, substring, etc., ela gera uma nova String e descarta a String mais antiga para coleta de lixo. Essas são operações pesadas e geram muitos resíduos na heap. Portanto, o Java fornece as classes StringBuffer e StringBuilder que devem ser usadas para manipulação de String. StringBuffer e StringBuilder são objetos mutáveis em Java. Eles oferecem métodos append(), insert(), delete() e substring() para manipulação de String.

StringBuffer vs StringBuilder

Desempenho de 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

StringBuffer era a única escolha para manipulação de strings até o Java 1.4. No entanto, possui uma desvantagem: todos os seus métodos públicos são sincronizados. StringBuffer oferece segurança de thread, mas a um custo de desempenho. Na maioria dos cenários, não usamos String em um ambiente multithread. Assim, o Java 1.5 introduziu uma nova classe, StringBuilder, semelhante ao StringBuffer, exceto pela segurança de thread e sincronização. StringBuffer possui alguns métodos extras, como substring, length, capacity, trimToSize, etc. No entanto, esses métodos não são necessários, pois todos estão presentes em String também. Por isso, esses métodos nunca foram implementados na classe StringBuilder. StringBuffer foi introduzido no Java 1.0, enquanto a classe StringBuilder foi introduzida no Java 1.5 após analisar as deficiências do StringBuffer. Se você estiver em um ambiente de thread único ou não se importar com a segurança de thread, deve usar StringBuilder. Caso contrário, use StringBuffer para operações seguras em threads. É evidente que o desempenho de StringBuilder é melhor do que o de StringBuffer, mesmo em um ambiente de thread único. Essa diferença de desempenho pode ser causada pela sincronização nos métodos de StringBuffer.

String vs StringBuffer vs StringBuilder

  1. String é imutável, enquanto StringBuffer e StringBuilder são classes mutáveis.
  2. StringBuffer é seguro para threads e sincronizado, enquanto StringBuilder não é. Por isso, StringBuilder é mais rápido que StringBuffer.
  3. O operador de concatenação de Strings (+) internamente utiliza a classe StringBuffer ou StringBuilder.
  4. Para manipulações de Strings em um ambiente não multithread, devemos usar StringBuilder; caso contrário, utilizar a classe StringBuffer.

Isso resume as principais diferenças entre String, StringBuffer e StringBuilder. StringBuilder é mais adequado que StringBuffer na maioria dos cenários de programação geral. Referências:

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