백준 온라인 저지 문제를 처음 풀었을 당시 순조롭게 풀고 있던 나는 멘붕에 빠졌었다.
입력을 받을 때 대부분 프롬프트 출력 없이 공백을 구분하여 받게 되는데 Scanner를 사용하면 손쉽게 해결할 수 있었다.
하지만...
해당 문제의 경우 빠른 처리 시간을 위해 Scanner 대신 BufferedReader를 사용하여 문제를 풀라는 것이었다.
BufferedReader를 사용하는 방법은 알고 있었지만 해당 클래스는 문자열을 분리해서 입력을 받는 기능이 없었고
해당 문제를 풀기 위해 StringTokenizer라는 클래스에 대해 추가적으로 알게 되었다.
StringTokenizer란?
StringTokenizer란 말 그대로 문자열(String)을 토큰화(Tokenizer)한다는 뜻이다.
즉 문자열을 분리된 조각인 토큰으로 관리할 수 있게끔 해주는 클래스다.
설정한 구분자를 기준으로 문자열을 나눠준다.
java.util 안에 StringTokenizer를 import하여 사용이 가능하다.
StringTokenizer 사용법
- 공백으로 구분하여 나눠주기
import java.util.StringTokenizer;
public class Main
{
public static void main(String[] args) {
String str = "저는 초보 개발자 입니다.";
StringTokenizer st = new StringTokenizer(str); // 객체 생성
while(st.hasMoreTokens()){
System.out.println(st.nextToken()); // 출력
}
}
}
저는
초보
개발자
입니다.
1. 문자열을 구분할 수 있는 StringTokenizer st객체를 생성해주고 토큰화할 문자열을 넣어준다.
2. 넣어준 문자열 옆에 구분자를 설정하지 않는다면 기본적으로 공백으로 구분한다.
3. nextToken() 메서드를 사용하여 분리된 문자열을 확인할 수 있다.
4. 여기서 hasMoreTokens() 메서드는 현재 객체에 남아있는 토큰이 있는지 확인한다.
있다면 true, 없다면 false를 반환한다.
반복문으로 토큰화된 문자열을 출력해본 결과 공백을 기준으로 문자열이 나눠진 것을 확인할 수 있다.
- 구분자를 기준으로 나눠주기
import java.util.StringTokenizer;
public class Main
{
public static void main(String[] args) {
String str = "저는!초보!개발자!입니다.";
StringTokenizer st = new StringTokenizer(str,"!");
while(st.hasMoreTokens()){
System.out.println(st.nextToken());
}
}
}
저는
초보
개발자
입니다.
만약 객체를 생성할 때 문자열뿐만 아니라 구분해줄 구분자를 같이 명시해준다면
해당 문자열은 그 구분자를 기준으로 문자열을 나눠서 토큰화한다.
만약 여기서 구분자를 포함하여 토큰으로 만들고 싶다면 구분자 옆에 true를 명시해주면 된다.
import java.util.StringTokenizer;
public class Main
{
public static void main(String[] args) {
String str = "저는!초보!개발자!입니다.";
StringTokenizer st = new StringTokenizer(str,"!",true);
while(st.hasMoreTokens()){
System.out.println(st.nextToken());
}
}
}
저는
!
초보
!
개발자
!
입니다.
여기서 true는 구분자를 포함하여 토큰화 한다는 의미이고 false는 구분자는 제외하고 토큰화 한다는 뜻이다.
디폴트는 false이므로 구분자의 토큰화가 필요 없을 시 생략해도 된다.
- StringTokenizer 메서드
리턴값 | 메서드명 | 기능 |
boolean | hasMoreTokens() | 남아있는 토큰이 있으면 true, 없으면 false를 반환 |
String | nextToken() | 객체에서 다음 토큰을 반환 |
String | nextToken(String delim) | delim 기준으로 다음 토큰을 반환 |
boolean | hasMoreElements() | hasMoreTokens()와 동일한 기능 |
Object | nextElement() | nextToken 메서드와 동일하지만 객체를 반환 |
int | countTokens() | 총 토큰의 개수를 반환 |
BufferedReader에 적용하기
import java.io.*;
import java.util.StringTokenizer;
public class Main
{
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
String str1 = st.nextToken();
String str2 = st.nextToken();
String str3 = st.nextToken();
String str4 = st.nextToken();
System.out.println(str1);
System.out.println(str2);
System.out.println(str3);
System.out.println(str4);
}
}
입력
나는 초보 개발자 입니다
출력
나는
초보
개발자
입니다
BufferedReader 객체를 생성해주고 readLine() 메서드를 StringTokenizer에 넣어준 뒤
StringTokenizer의 nextToken() 메서드를 사용해 문자열에 저장해 주면 입력된 문자열을 분리하여 사용할 수 있다.
문자열이 아닌 다른 타입으로 파싱도 가능하기 때문에 다양한 사용이 가능하다.
해당 기능은 겉보기에는 Scanner 클래스보다 복잡해보이지만 더욱 빠른 처리 속도를 보여준다.
해당 클래스를 공부한 덕분에 위에서 언급한 문제를 풀 수 있었고 지금도 문제를 풀면서 편한 Scanner도 좋지만
StringTokenizer를 사용하는데 더 익숙해지려고 노력하고 있다.
'개발 > JAVA' 카테고리의 다른 글
[JAVA/자바] 개인 미니 프로젝트 - 호텔 예약 시스템 (0) | 2025.01.29 |
---|---|
[JAVA/자바] 배열과 리스트 (2) | 2025.01.18 |
[JAVA/자바] Scanner와 BufferedReader의 차이 (2) | 2024.12.21 |