티스토리 뷰

자바에서 문자열을 다루고 싶을 때 우리는 별 의심없이 String 클래스를 사용하곤 한다. 하지만 상황에 따라서 어떤 문자열 클래스를 사용하느냐에 따라 자원을 더 절약할 수 있고, 능률이 올라갈 수 있는 법이다. 따라서 여러 문자열 클래스에 대해 정리해 보도록 하겠다.




String vs StringBuffer vs StringBuilder



위 세 클래스는 모두 문자열 클래스이다. 자바에서는 왜 이렇게 다양한 클래스들을 만들어 놓았을까? 각 클래스의 차이점을 아래 코드를 통해 확인해 보도록 하자.



<코드>

public class StringTest {

	public static void main(String[] args) {
		String str = new String("Hello");
		StringBuffer strbuf = new StringBuffer("Hello");
		StringBuilder strbld = new StringBuilder("Hello");
		
		str = str.concat(" World!");
		strbuf.append(" World!");
		strbld.append(" World!");
		
		System.out.println(str);
		System.out.println(strbuf);
		System.out.println(strbld);
	}

}


<결과>

Hello World!
Hello World!
Hello World!



결과가 모두 같다. 모두 문자열을 조작하는 기능이 존재한다는 것을 알 수 있다. 하지만 여기서 차이점이 있다. 문자열을 조작하는 방식에 있어서 각각의 클래스들이 차이점이 있다. 아래의 그림을 통해 알아보도록 하자.





생성된 초기에는 이와 같이 각 클래스의 참조변수들이 힙 영역의 객체들을 참조하는 모습이다. 여기서 각 객체에 문자열을 붙이는 메소드를 사용하면 String 클래스와 나머지 두 클래스는 내부적으로 다른 동작을 한다.





위 그림을 참고하여 이해를 해보자면, String 클래스는 현재 참조하는 객체의 참조를 끊고, 새로운 문자열 객체를 생성하여 그 객체를 참조하는 형태로 동작한다.


그리고 StringBuffer 클래스와 StringBuilder 클래스는 객체 내부에 버퍼가 존재하여 그 버퍼에 새로운 문자열을 추가하는 형식으로 동작하기 때문에 새로운 객체를 생성하지 않는다.


참고로 두 클래스 모두 버퍼의 크기는 초기 문자열의 길이 + 16 으로 초기화되니 알아두도록 하자.


따라서 문자열의 조작이 많이 필요한 경우에는 StringBuffer 클래스 또는 StringBuilder 클래스를 사용하는 것이 유리하다는 결론이 나온다. 그리고 일반적으로 문자열의 조작이 필요없다면, 문자열 상수로 선언하여 String 클래스를 사용하는 것이 좋아보인다.


이는 다른 클래스로 선언했을 때와 달리 String Contant Pool에 저장되어 고정된 문자열을 반복 생성하지 않고 사용하는 장점이 있다. 이 내용이 더 알고 싶다면 아래의 링크를 참고하도록 하자.



[Java]String s = "" vs String s = new String("")

http://hyoje420.tistory.com/16




StringBuffer vs StringBuilder



그럼 String 클래스와의 차이점은 알겠다. 근데 나머지 두 클래스는 무슨차이일까? API를 살펴보면 거의 대부분의 메소드들이 동일한 것을 살펴볼 수 있다. 이 두 클래스는 여러 개의 쓰레드로 프로그램이 구동될 때 차이점을 보인다.


StringBuffer 클래스는 동시에 이 객체에 접근했을 때, 동시성을 제어해주는 기능이 존재하고, StringBuilder 클래스는 동시성 제어기능을 제외하여 상대적으로 동작속도가 빠르다.


결국 쓰임세는 동일하나, 멀티쓰레드를 이용하여 하나의 문자열을 수정할 필요가 있다면 StringBuffer 클래스를 사용하는 것이 바람직할 것이고, 그렇지 않다면 StringBuilder 클래스를 사용하여 동작속도를 빠르게 하는 것이 좋을 것이다.




StringTokenizer



어떤 문자열이 특정한 구분자를 가지고 있다면, 각 구분자를 기점으로 문자열을 나누고 싶을 것이다. 그럴때 사용할 수 있는 클래스가 StringTokenize 클래스이다. 아래의 예시를 보자.



<코드>

import java.util.StringTokenizer;

public class StringTest {

	public static void main(String[] args) {
		StringTokenizer st = new StringTokenizer("사과 배 딸기 포도 석류 아보카도"," ");
		
		while(st.hasMoreTokens())
			System.out.println(st.nextToken());
	}

}


<결과>

사과
배
딸기
포도
석류
아보카도



위 코드를 보면 생성자에 첫번째 값으로는 구분자를 가지고 있는 문자열을 넣고, 두번째 값으로는 그 구분자가 어떤 문자인지 적어주고 있다. 여기서는 한 칸의 공백이므로 두번째 값으로 " "를 입력해준다.


그리고 분류된 토큰들을 순차적으로 참조하면서 토큰이 없어질 때까지 참조하면서 출력하는 것을 볼 수 있다.


여기서 hasMoreTokens() 메소드는 StringTokenizer 객체에 더이상 남아있는 토큰이 있다면, true를 리턴하고, 아니면 false를 리턴하는 메소드이다.


nextToken() 메소드는 현재의 토큰을 리턴하고, 다음 토큰의 위치를 가리키게 하는 메소드이다. 이 두 메소드를 이용하여 토큰을 모두 출력할 수 있는 것이다.




결론



정말 다양한 문자열 클래스가 존재한다. 항상 사용하던 String 클래스를 제외하고 다른 유용한 문자열 클래스들이 많다. 이렇게 클래스를 용도별로 숙지하고 필요한 상황에서 그때그때 잘 골라서 사용하는 것도 개발자에게 중요한 능력인 것 같다.




참고



뇌를 자극하는 Java 프로그래밍 - 김윤명

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함