본문
StringTokenizer
# StringTokenizer
StringTokenizer는 긴 문자열을 지정된 구분자(delimiter)를 기준으로 토큰(token)이라는 여러 개의작은 문자열로 잘라내는 데 사용된다. 예를 들어 "100,200,300,400"라는 문자열이 있을 때 ','를 구분자로 잘라내면 "100", "200", "300", "400"이라는 4개의 문자열(토큰)을 얻을 수 있다.
StringTokenizer를 이용하는 방법 이외에도 String의split(String regex)를 사용해서
String[] result = "100,200,300,400".split(",");과 같이 하거나
Scanner(String source)와 Scanner useDelimiter(String pattern)를 사용해서
Scanner sc2 = new Scanner("100,200,300,400").useDelimiter(",");과 같이 할 수도 있지만
이 두 가지 방법은 정규식 표현(Regular expression)을 사용해야하므로
정규식 표현에 익숙하지 않은 경우 StringTokenizer를 사용하는 것이 간단하면서도 명확한 결과를 얻을 수 있을 것이다.
그러나 StringTokenizer는 구분자로 단 하나의 문자 밖에 사용하지 못하기 때문에
보다 복잡한 형태의구분자로 문자열을 나누어야 할 때는 Scanner나 split메서드를 사용해야 할 것이다.
','를 구분자로 하는 StringTokenizer를 생성해서 문자열(source)을 나누어 출력하는 예제이다.
Source 01) TokenEx01.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | package tokenEx; import java.util.StringTokenizer; public class TokenEx01 { public static void main(String[] args) { String source = "100,200,300,400"; StringTokenizer st = new StringTokenizer(source, ","); while (st.hasMoreElements()) { System.out.println(st.nextToken()); } } } | cs |
Result)
1 2 3 4 | 100 200 300 400 | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | package tokenEx; import java.util.StringTokenizer; public class TokenEx02 { public static void main(String[] args) { String expression = "x=100*(200+300)/2"; /* * 생성자 StringTokenizer(String str, String delim, boolean returnDelims)를 * 사용해서 구분자로 토큰을 간주되도록 하였다. 구분자로여러 문자들을 지정한 것을 눈여겨보자. StringToken은 단 * 한문자의 구분자만 사용할 수 있기 때문에 "+-=()" 전체가 하나의 구분자가 아니라 각각의 문자가 모두 구분자라는 것에 주의해야한다. * 만일 반드시 두 문자 이상의 구분자를 사용해야 한다면, Scanner나 String클래스의 split메서드를 사용해야한다. */ StringTokenizer st = new StringTokenizer(expression, "+-*/=()", true); while (st.hasMoreTokens()) { System.out.println(st.nextToken()); } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 | x = 100 * ( 200 + 300 ) / 2 | cs |
Source 03) TokenEx03.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | package tokenEx; import java.util.StringTokenizer; public class TokenEx03 { public static void main(String[] args) { String source = "1,임승한,100,100,100|2,홍길동,95,80,80|3,아무개,70,90,90"; StringTokenizer st = new StringTokenizer(source, "|"); while (st.hasMoreTokens()) { String token = st.nextToken(); StringTokenizer st2 = new StringTokenizer(token, ","); while (st2.hasMoreElements()) { System.out.println(st2.nextToken()); } System.out.println("-----"); } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 1 임승한 100 100 100 ----- 2 홍길동 95 80 80 ----- 3 아무개 70 90 90 ----- | cs |
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | package tokenEx; import java.util.StringTokenizer; public class TokenEx04 { public static void main(String[] args) { String input = "삼십만삼천백십오"; System.out.println(input); System.out.println(hangulToNum(input)); } // 한글로 숫자롤 변경하는 메서드 private static long hangulToNum(String input) { long result = 0; long tmpResult = 0; long num = 0; final String NUMBER = "영일이삼사오육칠팔구"; final String UNIT = "십백천만억조"; final long[] UNIT_NUM = { 10, 100, 1000, 10000, (long) Math.pow(10, 8), (long) Math.pow(10, 12) }; StringTokenizer st = new StringTokenizer(input, UNIT, true); while (st.hasMoreTokens()) { String token = st.nextToken(); // 숫자인지,단위(UNIT)인지 확인한다. int check = NUMBER.indexOf(token); if (check == -1) { // 단위인 경우 if ("만억조".indexOf(token) == -1) { /* * "만삼천"과 같이 숫자 없이 바로 단위로 시작하는 경우에는 num의 값이 0이기 때문에 단위의 값을 곱해도 그 * 결과가 0이므로 삼항 연산자를 이용해서 num의값을 1로 바꾼 후 단위값을 곱하도록 하였다. */ tmpResult += (num != 0 ? num : 1) * UNIT_NUM[UNIT.indexOf(token)]; } else { /* * "만역조"와 같이 큰 단위가 나오면 tmpResult에 저장된 값에 큰 단위 값을 곱해서 result에 * 저장하고 tmpResult는 0으로 초기화 한다. 예를 들어 "삼십만"은 tmpResult에 저장되어 * 있던 30에 10000을 곱해서 result에 저장하고, tmpResult는 0으로 초기화 한다. */ tmpResult += num; result += (tmpResult != 0 ? tmpResult : 1) * UNIT_NUM[UNIT.indexOf(token)]; tmpResult = 0; } num = 0; } else { // 숫자인 경우 num = check; } } return result + tmpResult + num; } } | cs |
1 2 | 삼십만삼천백십오 303115 | cs |
result는 실제 결과 값을 저장하기 위한 공간이라는 것을 알아두자.
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 | package tokenEx; import java.util.StringTokenizer; public class TokenEx05 { public static void main(String[] args) { String data = "100,,,200,300"; String[] result = data.split(","); StringTokenizer st = new StringTokenizer(data, ","); for (int i = 0; i < result.length; i++) { System.out.print(result[i] + "|"); } System.out.println("개수 : " + result.length); int i = 0; for (; st.hasMoreTokens(); i++) { System.out.print(st.nextToken() + "|"); } System.out.println("개수 : " + i); } } | cs |
1 2 | 100|||200|300|개수 : 5 <-- split() 사용결과 100|200|300|개수 : 3 <-- StringTokenizer 사용결과 | cs |
StringTokenizer는 빈 문자열을 토큰으로 인식하지 않기때문에 인식하는 토큰 개수가 서로 다른 것을 알 수 있다.
데이터를 토큰으로 바로바로 잘라서 반환하는 StringTokenizer보다 성능이 떨어질 수 밖에 없다.
그러나 데이터의 양이 많은 경우가 아니라면 별 문제가 되지 않으므로 크게 신경쓸 부분은 아니다.
댓글