[JAVA] split vs StringTokenizer

2022. 6. 9. 18:45Programming의 세계/JAVA

StringTokenizer 클래스란?

문자열이 특정 구분자(delimeter)로 연결되어 있을 경우, 구분자를 기준으로 부분 문자열을 분리하기 위해서는 String의 split() 메소드를 이용하거나 java.util 패키지의 StringTokenizer 클래스를 이용할 수 있다.

 

StringTokenizer는 한 종류의 구분자로 연결되어 있을 경우, 사용이 편리하다는 장점이 있다.

 

StringTokenizer 사용방법

관련 클래스 임포트를 해야 작동한다.

import java.util.StringTokenizer;

 

1) 선언

StringTokenizer st = new StringTokenizer("문자열", "구분자");

 

2) 문자 나누며 꺼내기

2-1) 전체 토큰 수를 얻어 for문으로 looping 

String nameList = "코코/딩딩/기기/스스/칸칸";

//선언
StringTokenizer st = new StringTokenizer(text, "/"); // "/"로 문자열 나눔
int countTokens = st.countTokens(); //꺼내지 않고 남아있는 토큰의 수

//전체 토큰 수를 얻어 for문으로 looping 
for(int i = 0; i<countTokens; i++){
	String token = st.nextToken(); //nextToken()매서드를 통해 토큰을 하나씩 꺼낸다.
	System.out.println(token);
}

2-2) while문으로 looping하여 출력

//hasMoreTokens() 남아있는 토큰이 있는지 여부
while(st.hasMoreTokens()){ 
	String token = st.nextToken();
    System.out.println(token);
    }
 
 
 //결과창
 //코코
 //딩딩
 //기기
 //스스
 //칸칸

 


split()  VS  StringTokenizer_기능의 차이

둘다 문자열을 부분 문자열로 분리하는데 사용된다. 그러면 무슨 차이가 있을까?

구분 설명
split() String클래스의 메소드로 지정한 구분자로 문자열을 나눠 배열에 저장하는 역할을 하며 공백문자열도 포함한다.
StringTokenizer java.util에 포함되어 있는 메소드로 지정한 한가지 구분자로 문자열을 나눌 수 있다. 구분자를 생략하면 공백이 기본 구분자다.

 

1) 일반적인 상황 ( 데이터 + 구분자 + 데이터)

String str = "co,ding,gi,skan";

		String str = "co,ding,gi,skan";
		StringTokenizer tokenizer = new StringTokenizer(str, ",");
		// StringTokenizer 적용
		System.out.println("tokenizer적용");
		for (int i = 0; tokenizer.hasMoreTokens(); i++) {
			System.out.println(i + "번째 : " + tokenizer.nextToken());
		}
		// split 적용
		System.out.println("split()적용");
		String[] splitStr = str.split(",");
		for (int i = 0; i < splitStr.length; i++) {
			System.out.println(i + "번째 : " + splitStr[i]);
		}

차이가 없이 동일하게 동작한다.

 

2) 구분자 사이 데이터가 없는 경우 ( 구분자+ 구분자 를 포함한 데이터)

String str = "co,,ding,gi,,skan";

split의 경우 공백(null)의 데이터도 반환하는 것을 확인 할 수 있다.

 

3) 구분자로 끝나는 데이터를 표현하고 싶을때

String str = "co,,ding,gi,,skan,";

 

이고 구분자로 끝나는 경우도 split로 표현이 가능하다.

split의 기능을 보면 limit 설정이 가능하다는 것을 알 수 있다.

 

String str = "co,,ding,gi,,skan,";
StringTokenizer tokenizer = new StringTokenizer(str, ",");
        
// StringTokenizer 적용
System.out.println("tokenizer적용");
        
for (int i = 0; tokenizer.hasMoreTokens(); i++) {
	System.out.println(i + "번째 : " + tokenizer.nextToken());
}
        
// split 적용
System.out.println("split()적용");
String[] splitStr = str.split(",",-1);
for (int i = 0; i < splitStr.length; i++) {
	System.out.println(i + "번째 : " + splitStr[i]);
}

 

 


split()  VS  StringTokenizer(속도의 차이)

 

split 매소드는 인자로 정규표현식(regex)를 사용하기 때문에 속도측면에서는 StringTokenizer가 빠르다고 예상해볼 수 있다. 

그럼 맞는지 실제로 시간을 재보겠다.

 

구분자 "/"으로 나눈 1부터 10000까지 숫자 텍스트를 10000번 돌려보았다.

int runs = 10000; // 반복 횟수
int max = 10000; // 평문 작성을 위한 숫자 범위

// 1. sample 만들
StringBuilder sb = new StringBuilder();
for (int a = 0; a < max; a++) {
	sb.append("/" + a);
}

// 2. split 수행시간 측정
String text = sb.toString();
long splitStart = System.nanoTime();
for (int i = 0; i < runs; i++) {
	String[] tokens = text.split("/");
	List<String> result1 = new ArrayList<>();// 리스트에 값 다 넣는 시간 책정
	for (String t : tokens) {
		result1.add(t);
	}
}
        
long executeSplit = System.nanoTime() - splitStart;
// 3. tokenizer 측정
long tokenStart = System.nanoTime();
for (int i = 0; i < runs; i++) {
	StringTokenizer tokenizer = new StringTokenizer(text, "/");
	List<String> result2 = new ArrayList<String>();
	while (tokenizer.hasMoreElements()) {
		result2.add(tokenizer.nextToken());
	}
}
        
		long executeTokenizer = System.nanoTime() - tokenStart;// 리스트에 값 다 넣는 시간 책정
		System.out.println("split time : " + (executeSplit / runs / 1000.0));
		System.out.println("tokenizer time : " + (executeTokenizer / runs / 1000.0));

 

결과

 

 

오잉???

 

어랍쇼??

split가 더 빠르네?

5000번으로 더 늘려볼까???

그래도 더 빠르네?

 

runs값을 1000번으로 줄였을때는

 

tokinizer가 빨랐지만, 10000번 이상일때는 전부 split가 더 빨랐다.

이유가 뭘까?????

좋은 글이 있어서 이분의 글을 참고하면 될 것 같다.

이 글을 보면 split() 와  StringTokenizer의 구조 원리와 어느 쪽이 속도가 빠른지 명쾌히 알 수 있겠다.

 

https://codingdog.tistory.com/entry/java-split-메소드-stringtokenizer보다-항상-느릴까요

 

java split 메소드 : stringtokenizer보다 항상 느릴까요?

 네이버 블로그에 올린 옛날 글에 질문이 하나 달렸습니다. 그 질문에 대한 답변을 해 보겠습니다. java에서 어떠한 구분자를 기준으로 나누기 위해서 StringTokenizer를 쓰는 방법이 있습니다. 그런

codingdog.tistory.com

 

 

 

D.O.N.E!