String vs StringBuffer vs StringBuilder

Строка – один из самых широко используемых классов в Java. Классы StringBuffer и StringBuilder предоставляют методы для манипуляции строками. Мы рассмотрим различия между StringBuffer и StringBuilder. StringBuffer vs StringBuilder – популярный вопрос на собеседовании по Java.

String vs StringBuffer vs StringBuilder

Строка является одной из самых важных тем в собеседованиях по основам Java. Если вы пишете программу, которая что-то печатает в консоль, вы используете строку. Этот учебник направлен на основные возможности класса String. Затем мы сравним классы StringBuffer и StringBuilder.

String в Java

  1. Класс String представляет символьные строки, их можно создать двумя способами.

    String str = "ABC";
    // или 
    String str = new String("ABC");
    
  2. String неизменяем в Java. Поэтому его удобно использовать в многопоточной среде. Мы можем передавать его между функциями, потому что нет опасности несогласованности данных.

  3. При создании строки с использованием двойных кавычек JVM сначала ищет строку с таким же значением в пуле строк. Если находит, возвращает ссылку на объект строки из пула. В противном случае создает объект строки в пуле строк и возвращает ссылку. JVM экономит много памяти, используя одну и ту же строку в разных потоках.

  4. Если оператор new используется для создания строки, она создается в куче памяти.

  5. Оператор + перегружен для строк. Мы можем использовать его для конкатенации двух строк. Хотя внутренне он использует StringBuffer для выполнения этого действия.

  6. Переопределяет методы equals() и hashCode(). Две строки равны только в том случае, если у них одинаковая последовательность символов. Метод equals() учитывает регистр символов. Если вам нужна проверка без учета регистра, следует использовать метод equalsIgnoreCase().

  7. Строка использует кодировку UTF-16 для потока символов.

  8. String является финальным классом. Все поля являются финальными, за исключением “private int hash”. Это поле содержит значение функции hashCode(). Значение хэш-кода вычисляется только при вызове метода hashCode() в первый раз, а затем кэшируется в этом поле. Кроме того, хэш генерируется с использованием финальных полей класса String с некоторыми вычислениями. Поэтому каждый раз, когда вызывается метод hashCode(), результат будет одинаковым. Для вызывающего это кажется так, будто каждый раз происходят вычисления, но внутренне они кэшируются в поле hash.

String vs StringBuffer

Поскольку String является неизменяемым классом в Java, при выполнении операций с String, таких как конкатенация, подстрока и т. д., создается новый String и старый String удаляется для сборки мусора. Это операции, требующие больших ресурсов и создающие много мусора в куче. Поэтому в Java предоставлены классы StringBuffer и StringBuilder, которые следует использовать для операций с String. StringBuffer и StringBuilder являются изменяемыми объектами в Java. Они предоставляют методы append(), insert(), delete() и substring() для операций с String.

StringBuffer vs StringBuilder

StringBuffer был единственным выбором для манипуляции строками до Java 1.4. Но у него есть один недостаток: все его публичные методы синхронизированы. StringBuffer обеспечивает потокобезопасность, но за счет производительности. В большинстве сценариев мы не используем String в многопоточной среде. Поэтому в Java 1.5 был представлен новый класс StringBuilder, который похож на StringBuffer за исключением потокобезопасности и синхронизации. У StringBuffer есть дополнительные методы, такие как substring, length, capacity, trimToSize и т. д. Однако они не требуются, так как все они присутствуют в String. Поэтому эти методы никогда не были реализованы в классе StringBuilder. StringBuffer был введен в Java 1.0, тогда как класс StringBuilder был введен в Java 1.5 после выявления недостатков StringBuffer. Если вы находитесь в однопоточной среде или не заботитесь о потокобезопасности, вы должны использовать StringBuilder. В противном случае используйте StringBuffer для потокобезопасных операций.

Производительность StringBuilder против 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

Ясно, что StringBuilder работает лучше, чем StringBuffer, даже в случае однопоточной среды. Это различие в производительности может быть вызвано синхронизацией в методах StringBuffer.

Строка против StringBuffer против StringBuilder

  1. Строка неизменяема, в то время как StringBuffer и StringBuilder – изменяемые классы.
  2. StringBuffer является потокобезопасным и синхронизированным, в то время как StringBuilder – нет. Вот почему StringBuilder быстрее StringBuffer.
  3. Оператор конкатенации строк (+) внутренне использует класс StringBuffer или StringBuilder.
  4. Для манипуляций со строками в немногопоточной среде следует использовать StringBuilder, в противном случае – класс StringBuffer.

Вот и всё для краткого обзора различий между String, StringBuffer и StringBuilder. В большинстве общих сценариев программирования StringBuilder лучше подходит, чем StringBuffer. Ссылки:

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