언어/Java

[Java] String과 StringBuffer/StringBuilde

개발자들아제발자 2023. 5. 21. 17:47

String이란?

String 클래스는 문자열을 다루는 클래스이며 불변하다. 즉, String 객체에 값이 초기에 할당되면 그 값은 변경되지 않는다.

 

String 객체 생성방법

1. 리터럴을 이용하여 String 객체 생성

- String a1 = "a";

- String Constant Pool에 저장

 

2. new 연산자를 이용하여 String 객체 생성

- String a2 = new String("a");

- Heap 영역에 저장

 

a1과 a2는 서로 참조하는 곳이 다르기 때문에 a1 = a2는 false이다.

 

String 특징 - 불변

String a1 = "a";
a1 += "a";

1. 'a1' 변수에 'a' 리터럴을 이용해 String 객체 생성

2. 'a1' 변수에 'a' 리터럴 추가로 연산

3. 기존 String Constant Pool에 있던 'a'와 2에서 추가된 'a'가 연산되면서 'aa'라는 새로운 객체 생성

4. 1에서 생성되었던 String 객체 'a'는 GC에 의해 소멸된다.

 

String 비교

String a1 = "a";
String a2 = "a";

1. "a2" 변수에 "a"가 할당될때 먼저 String Constant Pool에 동일한 리터럴이 있는지 확인한다.

2. 동일한 리터럴이 있으면 해당 Constant Pool의 주소를 참조하고, 없으면 새로운 Constant Pool이 생성된다.

3. 따라서 a1과 a2는 같은 주소를 참조하기 때문에 a1 = a2는 true이다.

 

StringBuffer란?

String 클래스의 인스턴스는 한 번 생성되면 그 값을 읽기만 할 수 있고, 변경할 수는 없다. 이러한 문제를 해결하기 위해 StringBuffer 클래스의 인스턴스를 사용한다. StringBuffer 클래스의 인스턴스는 값을 수정하거나, 추가할 수 있다.

  • StringBuffer 클래스는 내부적으로 독립적인 공간 버퍼(Buffer)를 가진다.
  • 버퍼의 크기는 16개의 문자를 저장할 수 있는 크기이며, 생성자를 통해 크기를 설정할 수 있다.
  • 하지만 인스턴스 생성 시 사용자가 설정한 크기보다 16개의 문자를 저장할 수 있는 여유 공간을 가지고 생성한다.

 

StringBuffer의 메소드

1. append()

전달받은 값을 문자열로 반환하여 해당 문자열의 마지막에 추가

StringBuffer sb - new StringBuffer("Hello");
System.out.println(sb);  // Hello
System.out.println(sb.append("World"));  // Hello World
System.out.println(sb);  // Hello World

2. capacity()

인스턴스의 현재 버퍼 크기를 반환

StringBuffer sb1 = new StringBuffer();
StringBuffer sb2 = new StringBuffer("Hello");
System.out.printlnI(sb1.capacity());   // 16
System.out.printlnI(sb2.capacity());  // 21

3. delete()와 deleteCharAt()

지정한 인덱스의 해당하는 부분 문자열을 제거한다. 또는, 해당 인덱스의 문자 한개만 제거한다.

StringBuffer sb = new StringBuffer("Hello World!");
System.out.printlnI(sb);  // Hello World!
System.out.printlnI(sb.delete(5, 11);  // Hello!
System.out.printlnI(sb);  // Hello!
System.out.printlnI(sb.deleteCharAt(1));  // Hllo!
System.out.printlnI(sb);  // Hllo!

4. insert()

지정한 인덱스 위치에 입력 값을 문자여롤 변환한 수 해당 인덱스 위치에 문자열을 추가한다.

StringBuffer sb = new StringBuffer("Hello");
System.out.printlnI(sb);  // Hello
System.out.printlnI(sb.insert(5, " World! "));  // Hello World;

 

StringBuilder란?

한 번 생성된 String 클래스의 인스턴스는 여러 개의 문자열을 더할 때, 매번 새로운 인스턴스를 생성해야 한다.

만약 1000개 이상의 문자열이 있는데 모두 합치는 작업을 한다면 많은 인스턴스를 생성해야 하는데, 이러한 문제점을 해결할 때 사용하는 것이 StringBuilder이다.

StringBuilder sb = new StringBuilder();  // 객체 생성
sb.append("스트링").append("빌더");  // append()를 통해 문자열 연결
String str = sb.toString();  // toString()을 통해 문자열 변수에 할당

 

String과 StringBuffer의 차이

String a = new String("a");
a = a.concat("b");
a = s + "b";
// String 은 불변하기 때문에 기존의 것을 버리고 새로 할당하는 방식으로 사용 => 속도가 느려짐

StringBuffer sbuffer = new StringBuffer("a");
sbuffer.append("b");

StringBuilder sbuilder = new StringBuilder("a");
sbuilder.append("b");
// StringBuffer, StringBuilder는 변하기 때문에 기존의 것에서 append를 사용해서 값 변경 가능
  • String은 불변하기 때문에 concat, + 사용 시 기존 값을 버리고 새로 할당해서 1000번 이상 수행할 경우 급격히 느려진다.
  • 1000번 이상 사용할 경우 변하는 StringBuffer와 StringBuilder를 사용한다.
  • StringBuffer 공통 메소드 동기화로 인해 멀티 스레드 환경에서만 사용하고 그 외에는 StringBuilder를 사용하면 된다.

 

StringBuffer와 StringBuilder의 차이

가장 큰 차이점은 동기화의 유무이다. StringBuffer는 동기화 키워드를 지원하여 멀티쓰레드 환경에서 안전(thread-safe)

반대로, StringBuilder는 동기화를 지원하지 않기 때문에 단일쓰레드에서의 성능이 더 좋다.

 

결론

String: 문자열 연산이 적고 멀티쓰레드 환경일 경우

StringBuffer: 문자열 연산이 많고 멀티쓰레드 환경일 경우

StringBuilder: 문자열 연산이 많고 단일쓰레드이거나 동기화를 고려하지 않아도 되는 경우