본문 바로가기
Baeldung번역&공부/Java-basic

문자열 잇는 방법(String Concatenation in Java)

by ms727 2025. 2. 8.

원본 글: https://www.baeldung.com/java-string-concatenation

문자열을 잇는 작업은 흔한 일입니다. 문자열을 잇기 위한 conact()함수나 "+"연산자와 같이 몇 개의 방법을 탐구하고 요구사항에 적합한 것을 찾아서 적용해보는 글입니다.

1. Approaches to Concatenation

1.1 Using the "+" Operator

가장 흔한 방법 중 하나는 "+" 연산자를 통해서 문자열을 잇는겁니다.
"+"연산자는 다른 방법들보다는 좀 더 유연합니다. null에 대해서 어떤 오류도 주지않고, null을 문자열로 반환해 주기까지 합니다.

    @Test
    public void operator_null_test(){
        String stringOne = "minseok ";
        String stringTwo = null;
        Assertions.assertEquals("minseok null", stringOne + stringTwo);
    }

컴파일러는 "+' 연산자를 StringBuilder클래스의 append()함수로 변환해버립니다.
때문에 "+" 연산자는 암묵적으로 String 객체로 변환해버리기에 NullPointerExcpetion을 피할 수 있습니다.

1.2 Using the concat() Methods

concat() 함수는 호출한 문자열끝에 인자로 들어온 문자열을 추가하여 그 문자열을 반환합니다. String은 불변객체이기에 원본을 수정할 수 없기때문입니다.

    @Test
    public void concat_test() {
        String stringOne = "minseok";
        String stringTwo = " is a good man";
        Assertions.assertEquals("minseok is a good man", stringOne.concat(stringTwo));
    }

이전 예제에서는 stringOne는 기본 문자열 변수였습니다. concat()함수는 stringOne끝에 stringTwo을 이어 붙입니다.
concat()함수는 불면성을 지니기에 변수에 값을 할당해줘야합니다.

    @Test
    public void concat_immutable_test() {
        String stringOne = "minseok";
        String stringTwo = " is a good man";
        stringOne.concat(stringTwo);
        Assertions.assertNotEquals("minseok is a good man", stringOne);

        String result = stringOne.concat(stringTwo);

        Assertions.assertEquals("minseok is a good man", result);
    }

concat() 함수의 유용한 점 중 하나는 여러개의 문자열을 잇는데 사용될 수도 있는 것입니다.

    @Test
    public void concat_multiple_concatenation_test() {
        String stringOne = "minseok";
        String stringTwo = " is a";
        String stringThree = "good man";
        String result = stringOne.concat(stringTwo).concat(" ").concat(stringThree);
        String expected = "minseok is a good man";

        Assertions.assertEquals(expected, result);
    }

null에 대해서는 어떻게 동작할까요? 추가할 문자열이나 호출하는 문자열 모두 null이 될 수 없습니다. concat()은 NullPointerException을 발생시킬겁니다.

    @Test
    public void concat_null_test_throw_exception() {
        String stringOne = "minseok";
        String stringTwo = null;
        Assertions.assertThrows(NullPointerException.class, () -> stringOne.concat(stringTwo));
    }

1.3 StringBuilder Class

StringBuilder 클래스가 제공하는 append() 함수를 통해서 문자열을 이을 수 있습니다.

    @Test
    public void concat_null_test_throw_exception() {
        String stringOne = "minseok";
        String stringTwo = null;
        Assertions.assertThrows(NullPointerException.class, () -> stringOne.concat(stringTwo));
    }

StringBuffer클래스를 통해 위 방식과 비슷하게 문자열을 이을 수 있습니다. StringBuilder는 멀티쓰레드 환경에서 안전하지 않고, StringBuffer는 멀티쓰레드 환경에서도 안전합니다. 그러나 StringBuffer는 성능이 StringBuilder보다는 떨어집니다.

1.4 String format() Method

String클래스가 지니고있는 format() 함수를 통해서 문자열을 이을 수 있습니다. '%s'와 같은 문자를 통해서 여러개의 문자열을 이을 수 있습니다.

    @Test
    public void string_format_concatenation_test() {
        String stringOne = "minseok";
        String stringTwo = " is a good man";
        String result = String.format("%s%s", stringOne, stringTwo);
        String expected = "minseok is a good man";
        Assertions.assertEquals(expected, result);
    }

1.5 Approaches to Concatenation in Java 8 and Above

Java8버전 이후, String 클래스가 가지고 있는 join() 함수도 문자열을 이을 수 있습니다. 첫 번째 인자로 구분자를 가지며 이 값을 통해 문자열 사이에 구분자를 추가하고 잇습니다.

    @Test
    public void string_join_concatenation_test() {
        String stringOne = "minseok";
        String stringTwo = "is a good man";
        String result = String.join(" ", stringOne, stringTwo);
        String expected = "minseok is a good man";
        Assertions.assertEquals(expected, result);
    }

또한 Java8에는 StringJoiner 클래스가 추가되었습니다. 해당 클래스는 구분자, 접두사, 접미사를 가집니다.

    @Test
    public void stringJoinerClass_concatenation_test() {
        StringJoiner joiner = new StringJoiner(" ");
        joiner.add("minseok");
        joiner.add("is a good man");
        String expected = "minseok is a good man";

        Assertions.assertEquals(expected, joiner.toString());
    }

마지막으로 Java8에 추가된 Stream API를 통해서 문자열을 이을 수 있습니다.
Collectors클래스를 사용하는데, 이 클래스는 joining()함수를 가지고 있습니다. 이 함수는 String 클래스의 join()함수와 비슷하게 동작합니다.

    @Test
    public void stream_concatenation_test() {
        List<String> words = Arrays.asList("minseok", "is a good man");
        String result = words.stream().collect(Collectors.joining(" "));
        String expected = "minseok is a good man";

        Assertions.assertEquals(expected, result);
    }

2. Choosing an Approach

이제 다양한 측면을 고려하여 어떤 방식을 적용할지 생각해봅니다.

먼저, concat() 함수는 string에 대해서만 적용되고 "+"연산자는 모든 타입에 대하여 문자열로 변환합니다. 때문에 concat() 함수는 NullPointerException을 발생시킬 수 있습니다.
그리고 성능에 대해서도 이야기할 수 있습니다. concat() 함수는 "+"보다는 성능이 좋습니다. "+"연산자는 길이에 상관없이 새 문자열을 만들기 떄문입니다. concat()함수는 만약 추가될 문자열의 길이가 0보다 크지않으면 기존 객체를 반환하기에 이부분에 대해서는 성능적으로 이점이 있을 수 있습니다.

3. 결론

문자열을 잇는 여러 방법에 대해서 살펴봤습니다. 그리고 concat()과 "+" 연산자의 성능도 비교해봤습니다.


해당 글은 https://ms727.tistory.com/5 이글과 비슷합니다. 같이 확인해보면 좋을 것 같습니다.

테스트 코드: https://github.com/kkminseok/baeldung-test/blob/main/Java-String/src/test/java/manipulations/StringConcatenationTest.java