조종 다음은 개발

왜 String 를 그냥 사용하면 안될까?

String 은 immutable 하다. 즉, 변하지 않는다는 뜻이다.

String str = "hello";
str = "hello world";

위와 같이 "hello" 를 담고 있는 str 변수에 "hello world" 를 대입해주면 어떻게 될까?

"hello" 가 있던 공간에 world 를 추가해주는 것이 아니라 "hello world" 라는 새로운 문자열이 있는 메모리 공간을 str 이 가리키게 되는것이다.

String str = "hello world";
str.replace("hello", "hi");
System.out.println(str); // hello world

위 코드의 출력 결과는 어떨까? "hi world" 일까? 아니다. 여전히 "hello world" 이다.

replace 함수를 호출 했다 하더라도 str 은 변하지 않는다. 왜냐하면 string 은 immutable 하기 때문이다.

만약 바뀐 문자열을 가지고 싶다면 replace 함수의 리턴 해주는 문자열을 받아야 한다.

String str = "hello world";
str = str.replace("hello", "hi");
System.out.println(str); // hi world

string 의 toUpperCase(), subString() 등등 다른 함수들도 마찬가지이다. 모두 그러한 연산들이 적용된 새로운 문자열을 리턴해주지 문자열 그 자체를 바꾸지는 못한다.

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

그렇다면 위 연산을 하면 어떻게 될까? 새로운 문자열을 1000000 번이나 새롭게 String 객체를 만들고 주소값이 1000000 번 바뀌게 된다. 상상만 해도 메모리 효율이 매우 나쁠 것이다. 따라서 String 연산을 매우 많이 반복해야 하는 경우에는 String 보다는 StringBuilder 나 StringBuffer 를 사용하는 것이 좋다.

StringBuilder 와 StringBuffer

이 둘은 mutable 하다. 즉, 변경이 가능하다. StringBuilder / StringBuffer 는 미리 메모리 공간을 확보해두기 때문에 (특정 크기의 char 배열을 만들어두기 때문에) toString() 를 통한 immutable String 을 리턴하기 전까지는 메모리 공간 안에서 char 를 추가하고 변경하고 삭제할 수 있다.

그렇다면 이 둘의 차이점은 뭘까??

  • StringBuilder
    • 비동기적
    • 스레드 세이프 하지 못하다.
    • StringBuffer 에 비해 효율적이다.
  • StringBuffer
    • 동기적
    • 스레드 세이프
    • StringBuilder 에 비해 효율이 떨어짐
profile

조종 다음은 개발

@타칸

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!