String vs StringBuffer vs StringBuilder

문자열은 Java에서 가장 널리 사용되는 클래스 중 하나입니다. StringBuffer 및 StringBuilder 클래스는 문자열을 조작하는 메서드를 제공합니다. StringBuffer와 StringBuilder의 차이에 대해 살펴보겠습니다. StringBuffer vs StringBuilder는 인기있는 Java 인터뷰 질문입니다.

String vs StringBuffer vs StringBuilder

문자열은 핵심 Java 인터뷰에서 가장 중요한 주제 중 하나입니다. 콘솔에 무언가를 출력하는 프로그램을 작성하는 경우 문자열을 사용합니다. 이 튜토리얼은 String 클래스의 주요 기능에 초점을 맞추고 있습니다. 그런 다음 StringBuffer 및 StringBuilder 클래스를 비교할 것입니다.

Java에서의 문자열

  1. String 클래스는 문자열을 나타내며, 두 가지 방법으로 문자열을 인스턴스화할 수 있습니다.

    String str = "ABC";
    // 또는
    String str = new String("ABC");
    
  2. Java에서는 문자열이 불변(immutable)입니다. 따라서 멀티스레드 환경에서 사용하기에 적합합니다. 데이터 일관성에 대한 걱정이 없기 때문에 함수 간에 공유할 수 있습니다.

  3. 우리가 이중 따옴표를 사용하여 String을 생성할 때, JVM은 먼저 문자열 풀에서 동일한 값을 가진 String을 찾는다. 찾았다면, 문자열 풀에서 해당 문자열 객체의 참조를 반환한다. 그렇지 않으면, 문자열 풀에 String 객체를 생성하고 참조를 반환한다. JVM은 다른 스레드에서 동일한 String을 사용함으로써 많은 메모리를 절약할 수 있다.

  4. new 연산자를 사용하여 String을 생성하면 힙 메모리에 생성된다.

  5. + 연산자는 String에 대해 오버로딩 되어있다. 우리는 이를 사용하여 두 개의 문자열을 연결할 수 있다. 내부적으로는 StringBuffer를 사용하여 이 작업을 수행한다.

  6. 문자열은 equals() 및 hashCode() 메서드를 재정의합니다. 두 개의 문자열은 동일한 문자열 시퀀스를 갖는 경우에만 동일합니다. equals() 메서드는 대소문자를 구분합니다. 대소문자를 구분하지 않는 검사를 원하는 경우 equalsIgnoreCase() 메서드를 사용해야 합니다.

  7. 문자열은 문자 스트림에 대해 UTF-16 인코딩을 사용합니다.

  8. String은 최종 클래스입니다. “private int hash”를 제외한 모든 필드는 final입니다. 이 필드에는 hashCode() 함수 값이 포함되어 있습니다. 해시 코드 값은 hashCode() 메서드가 처음 호출될 때만 계산되고 이 필드에 캐시됩니다. 또한, 해시는 String 클래스의 final 필드와 일부 계산을 사용하여 생성됩니다. 따라서 hashCode() 메서드가 호출될 때마다 동일한 출력이 생성됩니다. 호출자에게는 매번 계산이 수행되는 것처럼 보이지만 내부적으로 해시 필드에 캐시되어 있습니다.

String vs StringBuffer

Java에서 String은 변경 불가능하기 때문에 연결(concatenation), 부분 문자열(substring) 등의 String 조작을 수행할 때마다 새로운 String을 생성하고 이전의 String을 가비지 컬렉션을 위해 버립니다. 이러한 작업은 무거운 작업이며 힙(heap)에 많은 가비지를 생성합니다. 따라서 Java는 String 조작에 사용되어야 할 StringBuffer와 StringBuilder 클래스를 제공합니다. StringBuffer와 StringBuilder는 Java에서 변경 가능한 객체입니다. 이들은 String 조작을 위한 append(), insert(), delete(), substring() 메서드를 제공합니다.

StringBuffer vs StringBuilder

StringBuffer는 Java 1.4까지 문자열 조작을 위한 유일한 선택 사항이었습니다. 하지만, 모든 공개 메소드가 동기화되어 있다는 단점이 있습니다. StringBuffer는 스레드 안전성을 제공하지만 성능에는 비용이 발생합니다. 대부분의 시나리오에서는 문자열을 다중 스레드 환경에서 사용하지 않습니다. 그래서 Java 1.5에서는 새로운 클래스인 StringBuilder를 소개했는데, 이는 StringBuffer와 유사하지만 스레드 안전성과 동기화의 차이가 있습니다. StringBuffer에는 substring, length, capacity, trimToSize 등의 추가 메소드가 있지만, 이들은 String에 이미 포함되어 있기 때문에 필요하지 않습니다. 그래서 이러한 메소드는 StringBuilder 클래스에 구현되지 않았습니다. StringBuffer는 Java 1.0에서 소개되었고, StringBuffer의 단점을 고려한 후 Java 1.5에서 StringBuilder 클래스가 소개되었습니다. 단일 스레드 환경이거나 스레드 안전성에 신경을 쓰지 않는 경우에는 StringBuilder를 사용해야 합니다. 그렇지 않으면 스레드 안전한 작업을 위해 StringBuffer를 사용하세요.

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

단일 스레드 환경에서도 StringBuilder가 StringBuffer보다 성능이 더 좋음을 명확히 알 수 있습니다. 이 성능 차이는 StringBuffer 메소드의 동기화 때문에 발생할 수 있습니다.

String vs StringBuffer vs StringBuilder

  1. 문자열은 불변(immutable)이며 StringBuffer와 StringBuilder는 가변(mutable) 클래스입니다.
  2. StringBuffer는 쓰레드 안전(thread-safe)하고 동기화(synchronized)되어 있지만, 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