StringBuilder와 toString();

buffet_psi·2023년 2월 27일
0

StringBuilder

문자열을 더할 때 사용하는 클래스
※String클래스와 비슷하게 동작하지만 중요한 차이점!!
String 클래스는 문자열을 더하게 되면 새로운 문자열 객체를 생성하므로 문자열을 더할 때마다 메모리 할당 및 해제가 발생합니다.
하지만 StringBuilder는 내부적으로 문자열을 가변적인 버퍼에 저장하므로 문자열을 더할 때마다 메모리를 새로 할당하지 않아도 되는 이점이 있어요
ex)1번 코드

StringBuilder sb = new StringBuilder(); // 빈 StringBuilder 객체 생성
// append 메소드를 사용하여 문자열을 더할 수 있음
sb.append("Hello");
sb.append(", ");
sb.append("world!");
sb.append("\n");

1번 코드의 경우 쉽게 설명하자면 처음에 "Hello"를 A 버퍼에 넣게 됩니다! 그리고 ", "를 A 버퍼 바로 붙이고 이러한 과정을 하다 보면 A 버퍼 안에 "Hello, world!"가 다 들어가 있습니다.

ex)2번코드

String str = "";
for (int i = 0; i < 10000; i++) {
    str += "a";
}

위 코드에서는 String 객체를 생성하고 문자열을 더할 때마다 새로운 String 객체를 생성합니다. 이렇게 되면 매번 새로운 객체를 생성하고 이전 객체를 가비지 컬렉션의 대상으로 만들어야 하므로, 성능상 문제가 있을 수 있습니다. 즉 i=0번째 일 때, "a"를 만들고 i=1일 때 "a"는 내버려 둔 상태에서 "aa"를 만들고 이 과정을 많이 하게 되면 쓰지도 "a","aa","aaa"...,"a9999"가 생성되어 "a9999" 앞에 쓰지도 않는 가비지 값들이 생기게 되는 것입니다!
따라서 문자열을 더할 때는 가능한 StringBuilder을 사용하는 것이 좋습니다!

StringBuilder쓰면서 알아두면 좋은 메서드!

toString();

ex)1번 코드

StringBuilder sb = new StringBuilder(); // 빈 StringBuilder 객체 생성
// append 메소드를 사용하여 문자열을 더할 수 있음
sb.append("Hello");
sb.append(", ");
sb.append("world!");
sb.append("\n");

1번코드에서 sb출력하면 "Hello, world!"가 나와야하는데 어떻게 출력해야하나요? System.out.println(sb);바로 쳐도 되지만 많이쓰는 방법은

String str = sb.toString();
System.out.println(str);	

이렇게 하는 방식을 많이 쓴답니다.
WHY? StringBuilder 클래스는 문자열을 동적으로 추가하고 수정하기 위해 사용되는 가변(mutable) 문자열 클래스입니다.StringBuilder는 내부적으로 문자 배열을 사용하여 문자열을 저장하므로, 출력하려면 toString() 메소드를 호출하여 문자열로 변환해야 합니다.
따라서 System.out.println(sb)를 호출하면, StringBuilder 객체의 toString() 메소드가 자동으로 호출되어 문자열로 변환되어 출력됩니다. 그래서 두 번째 방법인 String str = sb.toString(); System.out.println(str);을 사용하여 출력하는 것과 동일한 결과가 나타납니다.
하지만 StringBuilder의 toString() 메소드는 매번 호출될 때마다 새로운 문자열 객체를 생성하기 때문에, 문자열이 매우 긴 경우에는 성능상의 이슈가 발생할 수 있습니다. 따라서 StringBuilder의 내용을 출력할 때는, 가능하면 toString() 메소드를 한 번만 호출하여 문자열 객체를 생성하고 이후에는 생성된 문자열 객체를 재사용하는 것이 좋습니다.

(알아두면 좋은 상식 외전)
만약)

class 사람() {
    String 이름;
    int 나이;
    사람(){
        this.이름 = "name";
        this.나이 = 22;
    }
}

Main함수에서 사람 a사람 = new 사람();을 만들었다고 가정하겠습니다!

사람 클래스에서 이름과 나이를 System.out.println(a사람)문장으로 출력 싶다면?
System.out.println();의 특성은 ()안에있는 것을 문장화해서 출력합니다. 따라서 a사람을 문장화해서 출력할 인자를 주면 되겠네요 그래서 나온 답은

class 사람() {
    String 이름;
    int 나이;
    사람(){
        this.이름 = "name";
        this.나이 = 22;
    }
    @Override
    public String toString() {  =>메소드를 적어주고 출력방식을 정의해주면 된다 !!
        return "사람[이름=" + 이름 + ",나이=" + 나이 + "]";
}

이렇게 toString을 class에 있는 인자들을 return할 수 있게 Override 해주면 된답니다!

profile
노력과효율!

1개의 댓글

comment-user-thumbnail
2024년 3월 21일

안녕하세요! 궁금한게 있습니다ㅎㅎ
"StringBuilder의 toString() 메소드는 매번 호출될 때마다 새로운 문자열 객체를 생성하기 때문에, 문자열이 매우 긴 경우에는 성능상의 이슈가 발생" 한다고 적혀있는데
문자열이 길다는 부분이랑 성능이 떨어진다는 부분이 이해가 안됩니다!

여러 문자열을 StringBuilder 로 저장하여 StringBuilder.toString()으로 하면 할때 마다 새로운 객체를 형성하고 그로 인해 성능이 떨어진다고 이해하면 될까요???

답글 달기