백준 문제를 해결하던 중, 자꾸 메모리 초과를 맞았습니다.
원인은 바로 정답 문자열을 구성하는 문자열 클래스가 String이었다는 점 !
다시는 이런 실수를 하지 않겠다... 다짐하면서 String 클래스들을 알아보았습니다.
문자열 클래스의 종류
자바에는 크게 3개의 문자열 클래스가 존재하고, 각 클래스는 다음과 같은 특징을 가집니다.
- String
불변(immutable) 객체입니다. / 스레드 동기화를 고려할 필요가 없다.(안전하다. Thread-safe) - StringBuilder
가변(mutable) 객체입니다. / 스레드 동기화가 일어나지 않습니다. - StringBuffer
가변(mutable) 객체입니다. / 스레드 동기화가 일어납니다.
스레드 동기화란?
멀티 스레드 환경에서 여러 스레드가 하나의 공유자원에 접근할 때, 해당 스레드를 제외한 나머지 스레드는 접근하지 못하도록 막는 것입니다.
(추후에 더 상세히 다루겠습니다.)
String vs StringBuilder
가장 큰 차이는 String은 불변 객체, StringBuilder는 가변 객체라는 점 입니다.
// String 예제
String name = "전인혁"; // String
System.out.println(name); // "전인혁"
// StringBuilder 예제
import java.util.StringBuilder;
StringBuilder sb = new StringBuilder();
sb.append("전");
sb.append("인혁");
System.out.println(sb); // "전인혁"
불변 객체와 가변 객체의 차이?
불변 객체란, 클래스의 인스턴스가 생성된 후에 내부 상태 변경이 불가능한 객체를 뜻합니다.
반대로 가변 객체는, 인스턴스 생성 후에 내부 상태 변경이 가능한 객체를 뜻합니다.
String과 StringBuilder의 차이로 예시를 들자면,
- 불변 객체인 String은 문자열 더하기(+) 연산에서, 두 문자열이 합쳐질 때 기존 공간이 아닌 새로운 공간에 새로운 String 객체를 만들어 그 공간을 가리키도록 해서 문자열을 변경합니다.
- 반면, 가변 객체인 StringBuilder은 기존 값이 있던 메모리 공간에 문자열이 이어붙여지는 방식으로 문자열을 변경합니다.
따라서, 문자열 연산이 많은 경우에 StringBuilder가 성능적으로 크게 유리합니다.
결론
Java에 문자열을 구성하는 클래스가 3개나 있다는 것을 보고 많이 놀랐습니다.
하나씩 알아본 뒤, 그 특징을 파악하고 나니 각 클래스의 용도를 대략적으로 알 수 있었습니다.
상황에 따라 불변 객체인 String이 더 유리한 경우도 있을 것이고, ps에서 정답 출력할 때와 같이 StringBuilder가 더 유리한 경우도 있습니다.
프로그래밍에서의 대부분의 것들은 상황과 의도에 맞게 사용하도록 설계되어 있다는 점을 기억하며, 각 상황과 의도에 맞게 적절한 클래스를 선택하는 것도 실력임을 깨닫게 해준 공부였습니다.
'Java' 카테고리의 다른 글
[Java] String.format();으로 출력 서식 지정하기 (0) | 2023.01.18 |
---|---|
[Java] System.gc();와 Garbage Collection (0) | 2023.01.09 |
[Java] print 메소드와 BufferedWriter로 콘솔에 출력하기 (0) | 2023.01.09 |
[Java] Scanner와 BufferedReader로 콘솔에서 입력 받기 (0) | 2023.01.07 |