Programming/Java

[Java] 문자열 클래스: String, StringBuffer, StringBuilder

Isaac S. Lee 2024. 3. 21. 06:04

Java에서 문자열은 매우 중요한 데이터 형식으로 사용되며, 문자열을 효율적으로 처리하기 위해 String, StringBuffer, StringBuilder 세 가지 클래스가 제공된다. 개발자는 각 클래스를 사용 목적에 맞게 선택함으로써 프로그램의 성능과 안정성을 극대화할 수 있다.

 

Difference between String, StringBuilder, and StringBuffer (Source: String, StringBuffer, StringBuilder, Drashti Koladiya, 2021.10.21.)

 

String 클래스는 불변성으로 안정성을 보장하며, 문자열 수정이 거의 없는 경우에 적합하다.
StringBuffer 클래스는 멀티스레드 환경에서 안전하게 문자열을 동적으로 수정할 때 사용한다.
StringBuilder 클래스는 단일 스레드 환경에서 빠르게 문자열을 처리할 때 사용한다.

 

전체 코드

public class Main {
    public static void main(String[] args) {
        // String 예시
        String str1 = "Hello";
        String str2 = "World";
        String resultStr = str1 + " " + str2;
        System.out.println("String 예시: " + resultStr);

        // StringBuffer 예시
        StringBuffer buffer = new StringBuffer("Hello");
        buffer.append(" World");
        String resultBuffer = buffer.toString();
        System.out.println("StringBuffer 예시: " + resultBuffer);

        // StringBuilder 예시
        StringBuilder builder = new StringBuilder("Hello");
        builder.append(" World");
        String resultBuilder = builder.toString();
        System.out.println("StringBuilder 예시: " + resultBuilder);
    }
}

 

실행 결과

String 예시: Hello World
StringBuffer 예시: Hello World
StringBuilder 예시: Hello World

각 예시에서 생성된 문자열은 모두 "Hello World"이지만, 각 클래스의 내부적인 처리 방식이 다르기 때문에 코드에서 사용된 방식들이 다르다. 어떤 차이가 있는지 알아보도록 하자.

 

💡String 클래스


String str = "Hello";
str += " World";

String 클래스는 불변(Immutable)한 특성을 가지고 있다. 즉, 한 번 생성된 String 객체는 그 값을 변경할 수 없다.

문자열 연산 시마다 새로운 String 객체가 생성되어 오버헤드가 발생한다.

멀티스레드 환경에서는 동기화에 대한 걱정이 없으며, 안전하게 사용할 수 있다.

문자열 연산이 적고, 주로 조회가 많은 환경에서 사용된다.

 

String 클래스 메서드

리턴 타입 메서드 사용 예시 예제 결과
char charAt(int index) 특정 위치의 문자 리턴 char ch = str.charAt(6); 'W'
boolean equals(Object anObject) 두 문자열 비교 boolean isEqual = str.equals("Hello World"); true
byte[] getBytes() byte[]로 리턴 byte[] bytes = str.getBytes(); byte 배열
byte[] getBytes(Charset charset) 주어진 문자셋으로 인코딩한 byte[]로 리턴 byte[] bytes = str.getBytes(StandardCharsets.UTF_8); byte 배열
int indexOf(String str) 문자열 내에서 주어진 문자열의 위치 리턴 int index = str.indexOf("World"); 6
int length() 총 문자의 수 리턴 int length = str.length(); 11
String replace(CharSequence target, CharSequence replacement) target 부분을 replacement로 대치한 새로운 문자열 리턴 String replacedStr = str.replace("World", "Java"); "Hello Java"
String substring(int beginIndex) beginIndex 위치에서 끝까지 잘라낸 새로운 문자열 리턴 String subStr1 = str.substring(6); "World"
String substring(int beginIndex, int endIndex) beginIndex 위치에서 endIndex 전까지 잘라낸 새로운 문자열 리턴 String subStr2 = str.substring(0, 5); "Hello"
String toLowerCase() 알파벳 소문자로 변환한 새로운 문자열 리턴 String lowerCaseStr = str.toLowerCase(); "hello world"
String toUpperCase() 알파벳 대문자로 변환한 새로운 문자열 리턴 String upperCaseStr = str.toUpperCase(); "HELLO WORLD"
String trim() 앞뒤 공백을 제거한 새로운 문자열 리턴 String trimmedStr = " Hello ".trim(); "Hello"
String valueOf(int i) / valueOf(double d) 기본 타입 값을 문자열로 리턴 String intStr = String.valueOf(10); "10"
      String doubleStr = String.valueOf(3.14); "3.14"

 

String 클래스 메서드 전체 코드

public class Main {
    public static void main(String[] args) {
        // 문자열 "Hello"를 변수에 할당합니다.
        String str = "Hello";

        // charAt() 메서드를 사용하여 특정 위치의 문자를 가져와 출력합니다.
        char ch = str.charAt(1);
        System.out.println("charAt(1): " + ch);

        // equals() 메서드를 사용하여 두 문자열을 비교합니다.
        boolean isEqual = str.equals("Hello");
        System.out.println("equals(\"Hello\"): " + isEqual);

        // indexOf() 메서드를 사용하여 문자열 내에서 특정 문자열의 위치를 찾습니다.
        int index = str.indexOf("e");
        System.out.println("indexOf(\"e\"): " + index);

        // length() 메서드를 사용하여 문자열의 길이를 출력합니다.
        int length = str.length();
        System.out.println("length(): " + length);

        // replace() 메서드를 사용하여 문자열의 일부를 다른 문자열로 대체합니다.
        String replacedStr = str.replace("Hello", "Hi");
        System.out.println("replace(\"Hello\", \"Hi\"): " + replacedStr);

        // substring() 메서드를 사용하여 부분 문자열을 추출합니다.
        String subStr = str.substring(1, 3);
        System.out.println("substring(1, 3): " + subStr);

        // toLowerCase() 메서드를 사용하여 문자열을 소문자로 변환합니다.
        String lowerCaseStr = str.toLowerCase();
        System.out.println("toLowerCase(): " + lowerCaseStr);

        // toUpperCase() 메서드를 사용하여 문자열을 대문자로 변환합니다.
        String upperCaseStr = str.toUpperCase();
        System.out.println("toUpperCase(): " + upperCaseStr);

        // trim() 메서드를 사용하여 문자열의 앞뒤 공백을 제거합니다.
        String trimmedStr = "  Hello  ".trim();
        System.out.println("trim(): \"" + trimmedStr + "\"");

        // valueOf() 메서드를 사용하여 기본 타입 값을 문자열로 변환합니다.
        String intStr = String.valueOf(10);
        System.out.println("valueOf(10): " + intStr);

        // double 타입 값을 문자열로 변환합니다.
        String doubleStr = String.valueOf(3.14);
        System.out.println("valueOf(3.14): " + doubleStr);
    }
}

 

실행 결과

charAt(1): e
equals("Hello"): true
indexOf("e"): 1
length(): 5
replace("Hello", "Hi"): Hi
substring(1, 3): el
toLowerCase(): hello
toUpperCase(): HELLO
trim(): "Hello"
valueOf(10): 10
valueOf(3.14): 3.14

 

💡StringBuffer 클래스


StringBuffer buffer = new StringBuffer("Hello");
buffer.append(" World");

StringBuffer 클래스는 가변(Mutable)한 특성을 가지고 있다. 따라서 문자열을 동적으로 수정할 수 있다.

문자열 연산 시 새로운 객체를 생성하지 않고, 기존의 StringBuffer 객체를 수정한다.

멀티스레드 환경에서는 동기화가 가능하므로 스레드 안전(Thread-Safe)하게 사용할 수 있다.

 

StringBuffer 클래스 메서드

메서드 설명 예제 결과
append() 매개변수로 입력된 값을 문자열로 변환하여 StringBuffer에 추가 StringBuffer sb = new StringBuffer("Hello"); sb.append(" world"); sb = "Hello world"
capacity() StringBuffer 인스턴스의 버퍼 크기를 반환 StringBuffer sb = new StringBuffer(10); sb.append("ABCD"); int bufferSize = sb.capacity(); bufferSize = 100, sb = "ABCD"
charAt(int index) 지정된 위치(index)에 있는 문자를 반환 StringBuffer sb = new StringBuffer("Hello"); char c = sb.charAt(1); c = 'e'
delete(int start, int end) 시작 위치부터 끝 위치 사이에 있는 문자를 제거한다. 단, 끝 위치의 문자는 제외 StringBuffer sb = new StringBuffer("Hello"); sb.delete(1,4); sb = "Heo"
deleteCharAt(int index) 지정된 위치(index)의 문자를 제거 StringBuffer sb = new StringBuffer("Hello"); sb.deleteCharAt(1); sb = "Hllo"
insert(int pos, 매개변수) 지정된 위치(pos) 앞에 두 번째 매개변수로 받은 값을 문자열로 변환하여 추가 StringBuffer sb = new StringBuffer("0123456"); sb.insert(4,'ABC'); sb = "0123ABC456"
replace(int start, int end, String str) 지정된 범위의 문자들을 주어진 문자열로 변경. End 위치는 범위에 포함하지 않음 StringBuffer sb = new StringBuffer("0123456"); sb.replace(3, 6, "AB"); sb = "012AB6"
reverse() StringBuffer 인스턴스에 저장된 문자열의 순서를 거꾸로 나열 StringBuffer sb = new StringBuffer("0123456"); sb.reverse(); sb = "6543210"
setCharAt(int index, char ch) 지정된 위치의 문자를 주어진 문자로 변경 StringBuffer sb = new StringBuffer("0123456"); sb.setCharAt(5, 'A'); sb = "01234A6"
setLength(int newLength) 문자열의 길이를 지정된 길이로 변경. 빈 공간은 null ('\u0000')로 변환 StringBuffer sb = new StringBuffer("0123456"); sb.setLength(5); sb = "01234"
toString() StringBuffer 인스턴스의 문자열을 String으로 변환 StringBuffer sb = new StringBuffer("0123456"); String str = sb.toString(); str = "0123456"
substring(int start) 지정된 시작 위치부터 끝까지의 문자열을 반환 StringBuffer sb = new StringBuffer("0123456"); String str = sb.substring(3); str = "3456"
substring(int start, int end) 시작 위치부터 끝 위치 전까지의 문자열을 반환 StringBuffer sb = new StringBuffer("0123456"); String str2 = sb.substring(3, 5); str2 = "34

 

StringBuffer 클래스 메서드 전체 코드

public class Main {
    public static void main(String[] args) {
        // StringBuffer 객체 생성
        StringBuffer buffer = new StringBuffer("Hello");

        // append() 메서드를 사용하여 문자열을 추가합니다.
        buffer.append(" World");
        System.out.println("append(): " + buffer);

        // capacity() 메서드를 사용하여 버퍼의 크기를 확인합니다.
        int bufferSize = buffer.capacity();
        System.out.println("capacity(): " + bufferSize);

        // charAt() 메서드를 사용하여 특정 위치의 문자를 가져옵니다.
        char ch = buffer.charAt(1);
        System.out.println("charAt(1): " + ch);

        // delete() 메서드를 사용하여 문자열 일부를 삭제합니다.
        buffer.delete(1, 4);
        System.out.println("delete(1, 4): " + buffer);

        // deleteCharAt() 메서드를 사용하여 특정 위치의 문자를 삭제합니다.
        buffer.deleteCharAt(1);
        System.out.println("deleteCharAt(1): " + buffer);

        // insert() 메서드를 사용하여 문자열을 특정 위치에 삽입합니다.
        buffer.insert(1, "ABC");
        System.out.println("insert(1, \"ABC\"): " + buffer);

        // replace() 메서드를 사용하여 문자열의 일부를 대체합니다.
        buffer.replace(3, 6, "DEF");
        System.out.println("replace(3, 6, \"DEF\"): " + buffer);

        // reverse() 메서드를 사용하여 문자열을 뒤집습니다.
        buffer.reverse();
        System.out.println("reverse(): " + buffer);

        // setCharAt() 메서드를 사용하여 특정 위치의 문자를 변경합니다.
        buffer.setCharAt(5, 'X');
        System.out.println("setCharAt(5, 'X'): " + buffer);

        // setLength() 메서드를 사용하여 문자열의 길이를 조정합니다.
        buffer.setLength(5);
        System.out.println("setLength(5): " + buffer);

        // toString() 메서드를 사용하여 StringBuffer를 String으로 변환합니다.
        String result = buffer.toString();
        System.out.println("toString(): " + result);

        // substring() 메서드를 사용하여 부분 문자열을 추출합니다.
        String subString = buffer.substring(3);
        System.out.println("substring(3): " + subString);
    }
}

 

실행 결과

append(): Hello World
capacity(): 21
charAt(1): e
delete(1, 4): H World
deleteCharAt(1): HWorld
insert(1, "ABC"): HABCWorld
replace(3, 6, "DEF"): HABCFWorld
reverse(): dlroWFCBAH
setCharAt(5, 'X'): dlroWXCBAH
setLength(5): dlroW
toString(): dlroW
substring(3): oW

 

💡StringBuilder 클래스


StringBuilder builder = new StringBuilder("Hello");
builder.append(" World");

StringBuilder 클래스도 가변(Mutable)한 특성을 가지고 있다. StringBuffer와 유사하지만 스레드 안전하지 않다. 따라서 단일 스레드 환경에서 사용할 때 더 빠르게 동작한다.

 

StringBuilder 클래스 메서드

메서드 설명 예제 결과
append(String str) 문자열 추가 sb.append("bbb") (이전 문자열) + "bbb"
insert(int offset, String str) offset 위치에 str 추가 sb.insert(2, "ccc") (이전 문자열의 2번 위치) + "ccc"
replace(int start, int end, String str) start부터 end-1까지의 문자열을 str로 대체 sb.replace(3, 6, "ye") (이전 문자열에서 3부터 5까지의 문자열) + "ye" + (이전 문자열의 6부터 끝까지)
substring(int start, int end) 인덱싱. start부터 end-1까지의 문자열 추출 sb.substring(3, 7) (이전 문자열에서 3부터 6까지의 문자열)
deleteCharAt(int index) 인덱스에 위치한 문자 하나 삭제 sb.deleteCharAt(3) (이전 문자열에서 3번 위치의 문자를 제거한 결과)
delete(int start, int end) start부터 end-1 까지의 문자 삭제 sb.delete(3, sb.length()) (이전 문자열에서 3부터 끝까지의 문자를 제거한 결과)
toString() StringBuilder 객체를 String으로 변환 sb.toString() StringBuilder 객체의 문자열 표현
reverse() 문자열을 뒤집음 sb.reverse() (이전 문자열을 뒤집은 결과)
setCharAt(int index, char c) index 위치의 문자를 c로 변경 sb.setCharAt(2, 'x') (이전 문자열에서 2번 위치의 문자를 'x'로 변경한 결과)
setLength(int len) 문자열 길이 조정 sb.setLength(5) (이전 문자열의 길이를 5로 조정한 결과)
trimToSize() 문자열의 저장된 char[] 배열의 사이즈 조정 sb.trimToSize() 문자열 뒷부분의 공백을 모두 제거한 결과

 

StringBuilder 클래스 메서드 전체 코드

public class Main {
    public static void main(String[] args) {
        // StringBuilder 객체 생성
        StringBuilder builder = new StringBuilder("Hello");

        // append() 메서드를 사용하여 문자열을 추가합니다.
        builder.append(" World");
        System.out.println("append(): " + builder);

        // insert() 메서드를 사용하여 문자열을 특정 위치에 삽입합니다.
        builder.insert(2, "ABC");
        System.out.println("insert(2, \"ABC\"): " + builder);

        // replace() 메서드를 사용하여 문자열의 일부를 대체합니다.
        builder.replace(3, 6, "DEF");
        System.out.println("replace(3, 6, \"DEF\"): " + builder);

        // substring() 메서드를 사용하여 부분 문자열을 추출합니다.
        String subString = builder.substring(3, 7);
        System.out.println("substring(3, 7): " + subString);

        // deleteCharAt() 메서드를 사용하여 특정 위치의 문자를 삭제합니다.
        builder.deleteCharAt(3);
        System.out.println("deleteCharAt(3): " + builder);

        // delete() 메서드를 사용하여 문자열의 일부를 삭제합니다.
        builder.delete(3, builder.length());
        System.out.println("delete(3, builder.length()): " + builder);

        // reverse() 메서드를 사용하여 문자열을 뒤집습니다.
        builder.reverse();
        System.out.println("reverse(): " + builder);

        // setCharAt() 메서드를 사용하여 특정 위치의 문자를 변경합니다.
        builder.setCharAt(2, 'X');
        System.out.println("setCharAt(2, 'X'): " + builder);

        // setLength() 메서드를 사용하여 문자열의 길이를 조정합니다.
        builder.setLength(5);
        System.out.println("setLength(5): " + builder);

        // toString() 메서드를 사용하여 StringBuilder를 String으로 변환합니다.
        String result = builder.toString();
        System.out.println("toString(): " + result);
    }
}

 

실행 결과

append(): Hello World
insert(2, "ABC"): HeABCllo World
replace(3, 6, "DEF"): HeDEFlo World
substring(3, 7): DEFl
deleteCharAt(3): HeFlo World
delete(3, builder.length()): HeF
reverse(): Feh
setCharAt(2, 'X'): FeX
setLength(5): FeX
toString(): FeX

 

참고 자료

String, StringBuffer, StringBuilder, Drashti Koladiya, 2021.10.21.

[Java] 자바 문자열을 다루는 String 클래스 메소드 총정리, 혼공족장, 2023.03.20.

[Java/자바] StringBuffer 클래스 사용법, Hyun / Log, 2022.10.24.