[ StringTokenizer Class ]
- C언어 strtok의 로직과 유사하지만 원본을 훼손하지 않음
- 문자열을 특정 문자열(구분자)로 나누어 (Token) 및 저장 및 처리
- String 클래스의 split()과 비슷하지만, 배열이 아닌 인스턴스 객체를 만들어 저장
- 인스턴스의 클래스 메소드를 통해 실행시마다 쪼개서 문자열을 반환받음
java.util 패키지는 기본 패키지가 아니기 때문에 import 해줘야 합니다. String의 split() 메소드와 비슷한 것 같지만 작동 방식이 달라 상황에 따라 더 편리한 경우가 생깁니다. 굳이 배열 저장공간을 따로 만들지 않고도 문자를 나눠서 확인할 수 있습니다. (필요한 문자열만 뽑아내기에 적합)
[ 생성자 ]
- (String str) : 공백 기준으로 문자열 분리
- (String str, String delim) : 두 번째 문자열에 속한 구분자 기준으로 문자열 분리
- (String str, String delim, boolean returnDelims) : 구분자를 포함할 것인지 여부 결정
먼저 C언어의 strtok()함수와 마찬가지로, 두 번째로 제공된 구분자 문자열은 문자열 전체가 아닌 각각의 글자가 구분자가 됩니다. 만약 ("ab@cd#ef$", "@#$")로 사용했다면 "@","#","$" 문자가 각각 구분자가 됩니다. 그리고 boolean returnDelims 인자를 추가하지 않았다면 기본적으로 구분자는 나누어진 문자열에 포함되지 않습니다.
작동 방식을 알아보기 위해 디버깅을 해보겠습니다. 먼저 새로운 인스턴스를 생성하면 인스턴스에 생성자로 넘겨준 원본 문자열과 구분자 문자열이 그대로 저장됩니다. String 클래스의 split()메소드가 한번에 다 잘라서 배열로 반환해주는 것과는 달리, 일단 자르지 않고 그대로 저장해둡니다. 또한 원본 문자열 자체는 건드리지 않습니다.
package study.first;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) {
String str = "ab@cd#ef$gh";
StringTokenizer token = new StringTokenizer(str, "@#$");
System.out.println(token.countTokens());
}
}
[ token.countTokens() ]
- 현재 남아있는 Token 갯수 반환
- Token : 구분자로 쪼개진 한 묶음 단위
- 한 번 쪼갤 때마다 앞에서부터 하나씩 사라진다고 보면 됨
한번도 문자열을 나누지 않고 생성만 해둔 상태이므로, currenPosition에는 문자열의 시작점인 인덱스 0이 저장되어 있습니다. 이 값의 위치를 커서(Cursor)라고 부릅니다. 커서 위치를 기준으로 Token이 몇 개가 남아 있는지 반환해주는 메소드입니다.
package study.first;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) {
String str = "ab@cd#ef$gh";
StringTokenizer token = new StringTokenizer(str, "@#$");
// 현재 남은 token 갯수 == 4 (ab, cd, ef, gh)
System.out.println(token.countTokens());
}
}
[ hasMoreTokens() / hasMoreElements() ]
- 현재 커서 기준으로 더 반환할 수 있는 Token이 남았는지 여부
- 둘 다 같은 메소드
- boolean 타입으로 true / false 반환
- while문으로 반복 수행할 때 true / false 값을 사용할 수 있음
package study.first;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) {
String str = "ab@cd#ef$gh";
StringTokenizer token = new StringTokenizer(str, "@#$");
// 현재 남은 token 갯수 == 4 (ab, cd, ef, gh)
System.out.println(token.countTokens());
System.out.println(token.hasMoreTokens()); // true
}
}
[ nextToken() ]
- 현재 커서를 다음 구분자 위치로 이동시킨 후, 그 이전의 문자열을 반환
- String 타입으로 반환
- 구분자를 다시 지정할 수 있음
다음 구분자 위치("@"의 위치)인 인덱스 2로 커서값이 변경되었습니다. 그리고 그 전의 Token을 String 타입으로 반환해줍니다. countTokens() 메소드는 커서 값을 기준으로 하므로, 남은 Token 수 3을 반환합니다.
package study.first;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) {
String str = "ab@cd#ef$gh";
StringTokenizer token = new StringTokenizer(str, "@#$");
String firstToken = token.nextToken();
System.out.println(firstToken); // "ab" 출력
// 현재 남은 token 갯수 == 3 (cd, ef, gh)
System.out.println(token.countTokens());
}
}
만약 구분자를 다시 지정해줬다면 커서를 새로 들어온 구분자가 있는 곳까지 옮기고 그 앞의 문자열을 반환해줍니다.
delimiters(구분자)값이 바뀌고 커서가 해당 위치로 옮겨짐
package study.first;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) {
String str = "ab@cd#ef$gh";
StringTokenizer token = new StringTokenizer(str, "@#$");
String firstToken = token.nextToken("$");
System.out.println(firstToken); // "ab" 출력
// 현재 남은 token 갯수 == 1 (gh)
System.out.println(token.countTokens());
}
}
[ nextElement() ]
- nextToken() 메소드와 동일하지만, Object 타입으로 반환
- String으로 형반환해서 String 타입 변수에 담아줄 수 있음
많이 사용할 일은 없을 것 같습니다. 참고로 Object 타입의 인스턴스지만, 래퍼클래스 및 String 클래스를 오버라이딩해줬기 때문에 toString() 메소드도 오버라이딩 되어 인스턴스 출력 시 해당 값을 출력하게 됩니다.
package study.first;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) {
String str = "ab@cd#ef$gh";
StringTokenizer token = new StringTokenizer(str, "@#$");
Object firstToken = token.nextElement();
System.out.println(firstToken); // "ab" 출력
// 현재 남은 token 갯수 == 3 (cd, ef, gh)
System.out.println(token.countTokens());
}
}
위의 메소드들을 이용해서 반복문으로 특정 문자열을 구분자로 나누어 출력할 수 있습니다.
package study.first;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) {
String str = "ab@cd#ef$gh";
StringTokenizer token = new StringTokenizer(str, "@#$");
while (token.hasMoreTokens()) {
System.out.print(token.nextToken() + " ");
}
}
}
그리고 만약 인스턴스 생성자에 구분자 포함 여부를 true로 줬다면 구분자 또한 하나의 Token으로 인식하여 아래와 같은 결과가 됩니다.
package study.first;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) {
String str = "ab@cd#ef$gh";
StringTokenizer token = new StringTokenizer(str, "@#$", true);
while (token.hasMoreTokens()) {
System.out.print(token.nextToken() + " ");
}
}
}
'■ JAVA > Study' 카테고리의 다른 글
[JAVA] 예외(Exception) 처리하기 (0) | 2021.03.03 |
---|---|
[JAVA] 컬렉션 프레임워크(컬렉션 API)★★★★(이거 보기)★★ (0) | 2021.03.03 |
[JAVA] java.lang.Enum (열거형) 주요 메소드 [1/1] (0) | 2021.02.28 |
[JAVA] java.lang.Math (수학계산) 주요 메소드 [1/1] (0) | 2021.02.27 |
[JAVA] java.lang.StringBuilder (문자열) 주요 메소드 [2/2] (0) | 2021.02.25 |