[JAVA] StringBuilder 사용법과 주요 메소드

2024. 2. 19. 16:01언어(Language)/JAVA

 

알고리즘 연습 문제를 풀다보면 BufferReader/BufferWriter만큼 StringBuilder도 많이 사용하는 것을 볼 수 있다. 그래서 이 StringBuilder는 무엇인지, String과 StringBuffer와의 차이점을 무엇인지 알아보자

 


String과 StringBuffer/StringBuilder와의 차이점

 

우선 String과 StringBuffer/StringBuilder와의 차이를 간단하게 알아보자.

이들의 가장 큰 차이점은 String은 불변 속성을 갖고 StringBuffer/StringBuilder는 그렇지 않다는 것이다.

 

String이 불변성을 갖는다는 concat이나 + 연산을 통해 값을 변경하면 원래 기존의 String 메모리에서 값이 바뀌는 것이 아니라, 기존의 String에 들어있던 값을 버리고 새로운 값을 재할당하게 된다. 처음에 할당한 String의 메모리 영역은 Garbage로 남아있다가 GarbageCollection에 의해 없어진다.

 

String은 불변성을 가지기 때문에 변하지 않는 문자열을 자주 읽어들이는 경우 사용하면 유리하다. 하지만 문자열 추가, 삭제, 수정 등의 연산이 자주 일어나는 경우에 String을 사용하면, 힙 메모리에 많은 Garbage가 생성되고, 이는 힙 메모리 부족으로 이어져 프로그램의 성능에 치명적 영향을 미칠 수 있다.

 

이를 해결하기 위해 나온 것이 StringBuffer/StringBuilder이다.

StringBuffer/StringBuilder는 가변성을 가지기 때문에 .append(), .delete() 등 동일 객체 내에서 문자열을 변경하는 것이 가능하다. 그렇기 때문에 문자열의 추가, 수정, 삭제가 빈번하게 발생할 경우 사용해야 한다.

 

아래의 사진은 문자열을 합치는 연산을 할 때의 각각의 수행 시간을 보여주는 표이다.

String의 concat을 사용하면, 나머지 StringBuffer와 StringBuilder의 .append()보다 속도가 현저히 느린 것을 볼 수 있다.

 

출처 : javapapers.com

 

 


StringBuffer vs StringBuilder

 

StringBuffer

: 동기화를 지원하여 멀티 쓰레드 환경에서 안전하다.

 

 

StringBuilder

: 동기화를 지원하지 않아 멀티 쓰레드 환경에 사용하기 적합하지 않다. 대신 동기화를 지원하지 않기에 단일 쓰레드에서  StringBuffer보다 성능이 뛰어나다.

 

=> 정리하자면 StringBuilder는 문자열의 연산이 자주 일어나는 단일 쓰레드 환경에서 사용하는 것이 유리하다.

 

 


StringBuilder의 사용법

 

public class Main {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        sb.append("문자열").append("연결");

        //String에 StringBuilder를 그대로 넣을 수는 없다. toString()을 붙여야 한다.
        String str = sb.toString();

        //두 println()은 같은 값을 출력한다.
        System.out.println(sb);
        System.out.println(str);
    }
}

//출력 결과
//문자열연결
//문자열연결

 

 

위의 코드와 같이 먼저 StringBuilder의 객체를 생성한 후, append()의 인자로 연결하고자 하는 문자열을 넣어서 StringBuilder의 객체를 통해 호출한다.

그리고 출력 시에는 toString()을 붙여야 하고, String 변수에 넣을 때에도 마찬가지이다.

 

 

반복문에서 StringBuilder를 사용한다면 아래와 같이 사용할 수 있다.

import java.util.ArrayList;

public class Main {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        ArrayList<String> list = new ArrayList<>();
        list.add("첫 번째, ");
        list.add("두 번째, ");
        list.add("세 번째, ");
        list.add("네 번째, ");
        list.add("다섯 번째, ");

        for (int i = 0; i < list.size(); i++) {
            sb.append(list.get(i));
        }
        System.out.println(sb);
    }
}

StringBuilder의 주요 메소드

 

StringBuilder append(String s)

문자열을 추가한다.

StringBuilder sb = new StringBuilder();
sb.append("abc");
sb.append(4).append("\n");

 

 

StringBuilder  insert(int offset, String str)

offset 위치에 문자(str)을 삽입한다.

sb.insert(int offset, String str);
sb.insert(2, "ccc);

 

 

StringBuilder replace(int start, int end, String s)

첫 번째와 두 번째 파라미터로 받는 숫자 인덱스에 위치한 문자열을 대체한다.

sb.replace(int index1, int index2, String str);
sb.replace(3, 6, "hi");

 

 

StringBuilder subStinrg(int start)

StringBuilder subStinrg(int start, int end)

파라미터가 하나일 경우 해당 인덱스부터 끝까지 인덱싱한다.

파라미터가 두 개일 경우 start부터 end - 1까지 인덱싱한다.

sb.substring(int start);
sb.substring(int start, int end);

sb.substring(5);
sb.substring(3, 7);

 

 

StringBuilder deleteCharAt(int index)

인덱스에 위치한 문자 하나를 삭제한다.

sb.deleteCharAt(int index);
sb.deleteCharAt(3);

 

 

StringBuilder delete(int start, int end)

start부터 end - 1까지의 문자를 삭제한다.

sb.delete(int start, int end);
sb.delete(3, sb.length());

 

 

StringBuilder toString()

String으로 변환한다.

sb.toString();

 

 

StringBuilder reverse()

해당 문자 전체를 뒤집는다.

sb.reverse();

 

 

StringBuilder setCharAt(int index, char ch)

index 위치의 문자를 ch로 치환해준다.

sb.setCharAt(int index, char ch);

 

 

StringBuilder setLength(int len)

현재 문자열보다 길게 조정하면 공백으로 채워지고, 현재 문자열보다 짧게 조정하면 나머지 문자는 삭제한다.

sb.setLength(int len);

 

 

StringBuilder trimToSize()

문자열이 저장된 char[] 배열 사이즈를 현재 문자열 길이와 동일하게 조정한다.

String 클래스의 trim()이 앞뒤 공백을 제거하는 것과 같이 공백 사이즈를 제공하는 것.

 배열의 남는 사이즈는 공백이므로, 문자열 뒷부분의 공백을 모두 제거해준다고 보면 된다.

sb.trimToSize();