String은 원래 불변이다

원래 String은 불변 객체이다. → 즉 내부 값은 변경 불가

그러므로, 객체의 값을 바꾸고 싶다면 기존의 값은 그대로 두고 기존 값 + 더할 값 을 통하여 새로운 객체를 생성해서 사용해야한다.

 

변경된 값을 기반으로 새로운 객체 생성시 단점

예를 들어, A,B,C,D 를 더하여 ABCD 라는 필드 값을 만들고 싶은데, 이때,

A + B 를 통해 AB 라는 새로운 객체가 만들어지고, AB+C라는 두번째 새로운 객체가 만들어지고,

ABC+D 라는 세번째 새로운 객체가 만들어진다.

이때 생성되는 새로운 객체들은 ABCD를 만들기 위한 발판일 뿐, 사용하거나 필요한 객체가 아니다.

(메모리 낭비 → 즉 GC대상)

 

어떻게 해결할 수 있을까?

String은 불변객체이다. 그러므로 계속 필요 없는 객체를 생성해가면서 값을 더해가야하는데, 만약 String이 가변이라면 어떨까?

Java는 이를 위해 StringBuilder라는 가변 String을 제공한다.


StringBuilder

StringBuilder 활용 시, 새로운 객체 생성을 할 필요가 없고, 객체 내부의 값을 바로 변경 가능

다만 주의점

항상 다른 곳에서 값이 변경될 수 있는 사이드 이펙트에 주의 해야함.

 

StringBuilder 사용 예

public class StringBuilderMain1 {

    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        sb.append("A"); // 바로 뒤에 문자열 추가
        sb.append("B");
        sb.append("C");
        sb.append("D");
        System.out.println("sb = " + sb);

        sb.insert(4, "Java"); //특정위치에 문자열 추가
        System.out.println("insert = " + sb);

        sb.delete(4, 8); //특정 위치 문자열 삭제
        System.out.println("delete = " + sb);

        sb.reverse();
        System.out.println("reverse = " + sb);

        String string = sb.toString();
        System.out.println("string = " + string);

    }
}

StringBuilder의 메서드

  • 일단 StringBuilder 객체를 생성해야함
  • append() : 현재 문자열 바로 뒤에 문자열 추가
  • insert(): 특정 위치에 문자열 추가
  • delete(): 특정 범위 문자열 삭제
  • reverse(): 문자열 뒤집기

언제 쓰는지?

문자열을 계속 입력 받아 문자열 길이가 무궁무진하게 길어질 때 사용하면 효율성이 좋다.

Java는 우리가 “str” + “str” 연산을 하면 자동으로 append 연산 형태로 최적화를 해주어 우리는 그냥 대부분의 상황에는 + 연산을 통해 문자열을 더해주면 된다.

하지만 반복문을 통해 앞으로 입력이 얼마나 있을지 모를 때(컴파일 시점), StringBuilder 객체를 생성하여 append 하도록 설정해주면, 자동으로 최적화되어 메모리 관리에 효율적이다.

StringBuilder를 직접 사용하면 좋은 경우

  1. 반복문에서 반복하여 문자를 연결할 때
  2. 조건문을 통해 동적으로 문자열을 조합할 때
  3. 복잡한 문자열의 특정 부분을 변경해야할 때
  4. 매우 긴 대용량 문자열을 다룰 때