StringTokenizer
문자열이 특정 구분자(delimiter)로 연결되어 있는 경우, 구분자를 기준으로 부분 문자열을 분리하기 위해 이용하는 클래스이다.
String.split() 메서드를 사용하여 문자열을 구분할 수도 있다. 일반적으로 코딩할 때 split() 메서드를 사용할 때의 속도와 StringTokenizer를 사용할 때의 속도가 그렇게까지 유의미한 차이가 나진 않지만, 시간제한이 있는 알고리즘 문제를 푸는 등의 경우는 속도가 비교적 빠른 StringTokenizer를 사용하는 게 좋다고 생각한다.
split() 메서드는 정규 표현식을 사용해 구분하고, StringTokenizer는 문자를 사용해 구분한다는 점에서도 차이가 존재한다.
StringTokenizer 사용법은 다음과 같다.
import java.util.StringTokenizer;
StringTokenizer st = new StringTokenizer("문자열", "구분자");
StringTokenizer 객체를 생성할 때 첫 번째 매개 값으로 분리할 문자열을 넣고, 두 번째 매개 값으로는 구분자를 준다.
두 번째 매개 값은 생략할 수 있는데 이러한 경우 기본적으로 공백, 개행 등이 구분자로 default 된다.
메서드
int countTokens()
꺼내지 않고 남아 있는 토큰의 수를 반환한다.
boolean hasMoreTokens()
남아 있는 토큰이 있는지의 여부를 true/false 값으로 반환한다.
String nextToken()
토큰을 하나씩 꺼내온다.
StringTokenizer 객체(줄여서 st라 한다.)에 토큰이 한 개만 저장되어 있다고 가정한 상황에서 nextToken() 메서드로 토큰을 하나 꺼내오면 st 객체에는 토큰이 없어진다. 이때 st 객체에서 더 이상 가져올 토큰이 없다면 nextToken() 메서드는 java.util.NoSuchElementException 예외를 발생시킨다.
그래서 nextToken() 메서드를 사용하기 전에 hasMoreTokens() 메서드 또는 countTokens() 메서드로 꺼내올 토큰이 있는지 확인한 후 nextToken() 메서드를 호출하는 것이 좋은 코딩 방법이다.
NoSuchElementException
쉬운 이해를 위해 NoSuchElementException과 관련된 잘못된 방법과 올바른 방법을 비교해본다.
java.util.NoSuchElementException 발생 예제
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 str;
String result = st.nextToken();
while((str = st.nextToken()) != null) {
if (str.length() > result.length()){
result = str;
}
}
// 생략
}
'It is time to study'와 같은 공백을 포함하는 문자열을 하나 입력받고, 공백을 기준으로 잘라 그중에서 가장 긴 문자열을 result 변수에 저장한다. 현 상황에서 result 값에는 study라는 문자열이 저장될 것이다.
StringTokenizer 객체 생성 시 첫 번째 매개 값(It is time to study)만 전달했으므로 구분자는 자동으로 공백이나 개행이 될 것이다.
필자는 nextToken() 메서드로 문자열을 가져오고, 만약 가져올 문자열-사실 문자열이 아닌, 정확히 말하자면 토큰-이 없다면 null을 반환할 줄 알았다. 그래서 while문 조건을 (st.nextToken() != null)로 두었다.
그런데 계속해서 while() 부분에서 java.util.NoSuchElementException 예외가 발생했다. while문 실행 전 countTokens() 메서드를 사용하여 토큰이 남아있는 것도 확인했는데 토큰이 없다고 예외가 뜨니 환장할 노릇이었다.
근데 당연한 거였다. study까지 다 읽고 나면 이후에는 토큰이 없기 때문에 그냥 바로 NoSuchElementException을 발생시키는 것이다. StringTokenizer는 토큰이 없다고 친절하게 null 값을 반환해주거나 하지 않는다. (오히려 예외를 발생시키는 게 더 친절할지도 모른다.)
따라서 다음과 같은 코드로 수정해야 예외가 발생하지 않고 제대로 돌아간다.
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 str;
String result = st.nextToken();
while(st.hasMoreTokens()) {
str = st.nextToken();
if (str.length() > result.length()) {
result = str;
}
}
// 생략
}
hasMoreTokens() 말고도 countTokens() 메서드를 사용해서도 작성해볼 수 있다.
while(st.countTokens() > 0) {
str = st.nextToken();
if (str.length() > result.length())
result = str;
}
NoSuchElementException 예외 검색하니까 온통 이것이 자바다 책 내용 복붙한 블로그만 나와서 갱장히 슬펏다.
StringTokenizer
문자열이 특정 구분자(delimiter)로 연결되어 있는 경우, 구분자를 기준으로 부분 문자열을 분리하기 위해 이용하는 클래스이다.
String.split() 메서드를 사용하여 문자열을 구분할 수도 있다. 일반적으로 코딩할 때 split() 메서드를 사용할 때의 속도와 StringTokenizer를 사용할 때의 속도가 그렇게까지 유의미한 차이가 나진 않지만, 시간제한이 있는 알고리즘 문제를 푸는 등의 경우는 속도가 비교적 빠른 StringTokenizer를 사용하는 게 좋다고 생각한다.
split() 메서드는 정규 표현식을 사용해 구분하고, StringTokenizer는 문자를 사용해 구분한다는 점에서도 차이가 존재한다.
StringTokenizer 사용법은 다음과 같다.
import java.util.StringTokenizer;
StringTokenizer st = new StringTokenizer("문자열", "구분자");
StringTokenizer 객체를 생성할 때 첫 번째 매개 값으로 분리할 문자열을 넣고, 두 번째 매개 값으로는 구분자를 준다.
두 번째 매개 값은 생략할 수 있는데 이러한 경우 기본적으로 공백, 개행 등이 구분자로 default 된다.
메서드
int countTokens()
꺼내지 않고 남아 있는 토큰의 수를 반환한다.
boolean hasMoreTokens()
남아 있는 토큰이 있는지의 여부를 true/false 값으로 반환한다.
String nextToken()
토큰을 하나씩 꺼내온다.
StringTokenizer 객체(줄여서 st라 한다.)에 토큰이 한 개만 저장되어 있다고 가정한 상황에서 nextToken() 메서드로 토큰을 하나 꺼내오면 st 객체에는 토큰이 없어진다. 이때 st 객체에서 더 이상 가져올 토큰이 없다면 nextToken() 메서드는 java.util.NoSuchElementException 예외를 발생시킨다.
그래서 nextToken() 메서드를 사용하기 전에 hasMoreTokens() 메서드 또는 countTokens() 메서드로 꺼내올 토큰이 있는지 확인한 후 nextToken() 메서드를 호출하는 것이 좋은 코딩 방법이다.
NoSuchElementException
쉬운 이해를 위해 NoSuchElementException과 관련된 잘못된 방법과 올바른 방법을 비교해본다.
java.util.NoSuchElementException 발생 예제
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 str;
String result = st.nextToken();
while((str = st.nextToken()) != null) {
if (str.length() > result.length()){
result = str;
}
}
// 생략
}
'It is time to study'와 같은 공백을 포함하는 문자열을 하나 입력받고, 공백을 기준으로 잘라 그중에서 가장 긴 문자열을 result 변수에 저장한다. 현 상황에서 result 값에는 study라는 문자열이 저장될 것이다.
StringTokenizer 객체 생성 시 첫 번째 매개 값(It is time to study)만 전달했으므로 구분자는 자동으로 공백이나 개행이 될 것이다.
필자는 nextToken() 메서드로 문자열을 가져오고, 만약 가져올 문자열-사실 문자열이 아닌, 정확히 말하자면 토큰-이 없다면 null을 반환할 줄 알았다. 그래서 while문 조건을 (st.nextToken() != null)로 두었다.
그런데 계속해서 while() 부분에서 java.util.NoSuchElementException 예외가 발생했다. while문 실행 전 countTokens() 메서드를 사용하여 토큰이 남아있는 것도 확인했는데 토큰이 없다고 예외가 뜨니 환장할 노릇이었다.
근데 당연한 거였다. study까지 다 읽고 나면 이후에는 토큰이 없기 때문에 그냥 바로 NoSuchElementException을 발생시키는 것이다. StringTokenizer는 토큰이 없다고 친절하게 null 값을 반환해주거나 하지 않는다. (오히려 예외를 발생시키는 게 더 친절할지도 모른다.)
따라서 다음과 같은 코드로 수정해야 예외가 발생하지 않고 제대로 돌아간다.
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 str;
String result = st.nextToken();
while(st.hasMoreTokens()) {
str = st.nextToken();
if (str.length() > result.length()) {
result = str;
}
}
// 생략
}
hasMoreTokens() 말고도 countTokens() 메서드를 사용해서도 작성해볼 수 있다.
while(st.countTokens() > 0) {
str = st.nextToken();
if (str.length() > result.length())
result = str;
}
NoSuchElementException 예외 검색하니까 온통 이것이 자바다 책 내용 복붙한 블로그만 나와서 갱장히 슬펏다.