Java String Builder 가변과 불변
String 타입은 불변으로 사용되고 이 클래스의 문제점이 있다.
기존 String 문제점 살펴보기
String str1 = "Hello, ";
String str2 = "World!";
String str3 = str1 + str2;
System.out.println(str3);
Hello, World!
String 객체의 더하기(+) 연산을 하여 문자열을 합쳐서 출력하는 것을 보여준다.
여기서 문제점이 발생되는데,
String 값을 수정하거나 추가할 때마다 새로운 new 연산이 일어나게 된다.
극단적인 코드를 살펴본다.
많은 문자를 더하는 코드다.
String str1 = "H" + "e" + "l" + "l" + "o";
// -> String("H") +String("e") + String("l") + String("l") + String("o")
// -> new String("He") + String("l") + String("l") + String("o")
// -> new String("Hel") + String("l") + String("o")
// -> new String("Hell") + String("o")
// -> new String("Hello")
- str 변수는 4개의 String 클래스가 추가 생성된다.
- 중간에 만들어진 "He", "Hel"... 사용하지 않는다.
- 마지막 new String("Hello"); 남기고 나머지 String 객체는 모두 GC의 대상이 된다.
불필요한 새 객체를 생성하고 변경하는 상황이 많다면 GC의 대상이 많아진다. 이는 결국 CPU 와 메모리 자원을 많이 사용되고 시스템 자원을 낭비하게 된다.
StringBuilder 클래스
StringBuilder 부모 클래스인 AbstractStringBuilder 자바에 내장되어 있다.
abstract sealed class AbstractStringBuilder implements Appendable, CharSequence
permits StringBuilder, StringBuffer {
/**
* The value is used for character storage.
*/
byte[] value;
...
}
코드를 살펴보면 value 변수가 final 키워드가 없어서 변경할 수 있다는 것을 알 수 있다.
StringBuilder 사용하기
StringBuilder sb = new StringBuilder();
sb.append("Hello ");
sb.append("World ");
System.out.println("append sb = " + sb);
sb.insert(6,"Call ");
System.out.println("insert sb = " + sb);
sb.delete(6, 11);
System.out.println("delete sb = " + sb);
sb.reverse();
System.out.println("reverse sb = " + sb);
String str = sb.toString();
System.out.println("str = " + str);
append sb = Hello World
insert sb = Hello Call World
delete sb = Hello World
reverse sb = dlroW olleH
문자열이 계속 바뀌도록 sb 변수로 StringBuilder 클래스로 생성하고 테스트하였다.
여러 메소드가 있지만 이 중 몇 가지 살펴 본다.
- append(String str)
- 문자열을 이어서 추가
- insert(int offset, String str)
- 특정 위치에 문자열 삽입
- delete(int start, int end)
- 특정 범위의 문자열을 제거
- reverse()
- 문자열을 뒤집는다.
가변의 StringBuilder 문자열 결과를 String 변수로 생성하여 불변으로 할당한다.
가변과 불변
String 불변 객체는 한번 생성되면 내용을 변경할 수 있고 변화를 줄 때마다 새로운 String 객체 생성으로 기존 객체는 버려져 처리 시간에 많은 소모가 일어난다.
StringBuilder 하나의 가변 객체로 문자열을 추가 삭제 수정하여 새로운 객체를 생성하지 않게하고 메모리 사용을 줄여 성능을 높인다. 단 불변이 아닌 만큼 사이드 이펙트에 주의한다.