기존 String의 경우 불변 객체다. 따라서 값을 변경할려면 String끼리 연결하여 새로운 String객체를 생성해주어야한다. 이는 String class의 threadsafe한 장점을 극대화한다.
문제는 이 과정에서 메모리할당과 메모리해제가 발생하면 성능적으로 좋지 않기때문에 새로운 대체안으로 Stringbuilder와 Stringbuffer가 등장하게 된다.
위에서 Stringbuilder와 Stringbuffer가 등장했다고 언급했는데, 위 두 클래스는 성능상 유사한점이 있다. 바로 변경가능하다는 것이다. 이것이 String과 가장 큰 차이다.
물론 디테일하게 다른 점도 있다. java api 문서를 보면 Stringbuffer 보다 Stringbuilder가 속도가 더 빠르기 때문에 사용하는 것을 권장한다. 하지만 Stringbuilder는 threadsafe하지 못한다. 즉 동기화가 보장되지 않는다. 반면에 Stringbuffer는 동기화가 보장된다.
class StringBuilder{
public static void main(String args[]){
StringBuilder sb=new StringBuilder();
// 기본생성자는 무조건 16자리 캐릭터배열(32byte)로 생성
System.out.println(sb.capacity()); // result: 16
sb.append("Hello");
//Hello가 추가되어도 배열길이를 초과하지 않으므로 16자리 반환
System.out.println(sb.capacity());//result: 16
sb.append("Java is my favourite language");
//문자열이 추가가 되었기 때문에 기존 capacity에 두배를 하고 2를 더한값을 반환함
System.out.println(sb.capacity());//result: 34
}
}
이부분에 있어서 왜 그럴까? 위의 Stringbuilder특징 1번을 생각해보자.
String은 불변적이라 값을 바꾸는 것이 불가능하다.
값을 바꾸는 것이 아니라 연산을 통해 새로운 Stirng객체를 생성한다.
따라서 이러한 단점을 Stringbuilder는 배열공간의 크기를 바꿀 수 있게하여 문자열의 추가, 수정, 삭제를 가능하게 한다.
이를 append(), insert(), delete() 등의 메소드를 통해 가능하게 한다.
public class StringBuilder {
public static void main(String[] args) {
StringBuilder sb1 = new StringBuilder("value1 ");
System.out.println("builderObject :"+sb1); // builderObject :value1
// 캐릭터 A추가
sb1.append('A');
System.out.println("after append = " + sb1); //after append = value1 A
자유자재로 char, boolean, double, float, int, long, Object, String, Stringbuilder값을 추가할 수 있다.
public class StringBuilder {
public static void main(String[] args) {
StringBuilder sb1 = new StringBuilder("programming");
System.out.println("string1 : "+sb1); // char배열로 되어있는 Stringbuilder객체를 반환해줌
String str1 = sb1.toString();
System.out.println("string1 after toString() :"+str1); // String으로 반환해줌
}
}
char배열로 되어있는 Stringbuilder객체를 문자열로 반환해주는 메소드