StringTokenizer와 String.split()

유방현·2024년 10월 23일

1. StringTokenizer 클래스

1.1 개요

  • java.util 패키지에 포함
  • 문자열을 지정된 구분자(delimiter)로 분리
  • 구분자를 하나의 문자로 취급
  • 빈 토큰을 무시함
  • 성능이 split()보다 좋음

1.2 생성자

// 기본 생성자 (구분자: 공백)
StringTokenizer st1 = new StringTokenizer("Hello World");

// 구분자 지정
StringTokenizer st2 = new StringTokenizer("Hello,World", ",");

// 구분자도 토큰으로 포함할지 여부 지정
StringTokenizer st3 = new StringTokenizer("Hello,World", ",", true);

1.3 주요 메서드

StringTokenizer st = new StringTokenizer("Hello,World,Java", ",");

// 다음 토큰 반환
String token = st.nextToken();

// 남은 토큰 수 반환
int count = st.countTokens();

// 다음 토큰 존재 여부 확인
boolean hasMore = st.hasMoreTokens();

// 모든 토큰 순회
while (st.hasMoreTokens()) {
    System.out.println(st.nextToken());
}

1.4 특징과 장점

  1. 성능이 우수함
  2. 간단한 문자열 분리에 적합
  3. 메모리 사용이 효율적
  4. Iterator처럼 순차적 접근 가능

1.5 한계

  1. 정규표현식 미지원
  2. 역방향 순회 불가
  3. 빈 토큰 무시
  4. 구분자를 하나의 문자로만 처리

2. String.split() 메서드

2.1 개요

  • String 클래스의 메서드
  • 정규표현식 지원
  • 결과를 문자열 배열로 반환
  • 빈 토큰 유지 가능

2.2 기본 사용법

// 기본 사용
String str = "Hello World Java";
String[] words = str.split(" ");

// 제한된 수의 토큰만 분리
String[] limitedWords = str.split(" ", 2);  // 최대 2개로 분리

// 정규표현식 사용
String[] tokens = "Hello,World;Java".split("[,;]");

2.3 정규표현식 활용

// 여러 구분자 사용
String str = "Hello,World;Java:Python";
String[] tokens = str.split("[,;:]");

// 공백 문자 처리
String str2 = "Hello   World\\tJava\\nPython";
String[] tokens2 = str2.split("\\\\s+");

// 특수문자 처리
String str3 = "Hello.World|Java";
String[] tokens3 = str3.split("[.|]");  // 점과 파이프로 분리

2.4 특징과 장점

  1. 정규표현식 지원
  2. 결과를 배열로 한 번에 접근 가능
  3. 빈 토큰 처리 옵션
  4. 분리 개수 제한 가능

2.5 한계

  1. StringTokenizer보다 성능이 떨어짐
  2. 정규표현식으로 인한 복잡성
  3. 메모리 사용량이 더 많음

3. 실용적인 사용 예제

3.1 CSV 파일 파싱

// StringTokenizer 사용
public static List<String[]> parseCSVWithTokenizer(String line) {
    List<String[]> result = new ArrayList<>();
    StringTokenizer st = new StringTokenizer(line, ",");
    String[] tokens = new String[st.countTokens()];
    int i = 0;
    while (st.hasMoreTokens()) {
        tokens[i++] = st.nextToken();
    }
    result.add(tokens);
    return result;
}

// split() 사용
public static List<String[]> parseCSVWithSplit(String line) {
    List<String[]> result = new ArrayList<>();
    String[] tokens = line.split(",", -1);  // 빈 필드 유지
    result.add(tokens);
    return result;
}

3.2 문장 분석

public static class SentenceAnalyzer {
    // StringTokenizer를 사용한 단어 수 계산
    public static int countWordsTokenizer(String sentence) {
        StringTokenizer st = new StringTokenizer(sentence);
        return st.countTokens();
    }

    // split()을 사용한 단어 수 계산
    public static int countWordsSplit(String sentence) {
        return sentence.split("\\\\s+").length;
    }

    // 고유 단어 수 계산
    public static int countUniqueWords(String sentence) {
        return new HashSet<>(Arrays.asList(sentence.split("\\\\s+"))).size();
    }
}

5. 선택 가이드

5.1 StringTokenizer 선택 시기

  1. 단순한 문자열 분리가 필요할 때
  2. 성능이 중요할 때
  3. 구분자가 단순할 때
  4. 빈 토큰을 무시해도 될 때

5.2 split() 선택 시기

  1. 정규표현식이 필요할 때
  2. 빈 토큰을 유지해야 할 때
  3. 결과를 배열로 한 번에 처리해야 할 때
  4. 복잡한 구분자 패턴이 필요할 때

6. 주의사항

  1. 정규표현식 특수문자 처리 (\\, ., |, `` 등)
  2. 빈 문자열 처리 차이
  3. 성능과 메모리 사용량 고려
  4. 대용량 데이터 처리 시 고려사항

7. 최신 Java에서의 대안

  1. Pattern.compile()과 함께 사용
  2. Scanner 클래스 활용
  3. Java 8 Stream API와 결합
// Stream API 활용 예제
Arrays.stream(text.split(","))
      .map(String::trim)
      .filter(s -> !s.isEmpty())
      .collect(Collectors.toList());

0개의 댓글