문제

방금 Java의 스캐너 클래스에 대해 배웠고 이제 StringTokenizer 및 String.split과 어떻게 비교/경쟁하는지 궁금합니다. StringTokenizer와 String.split은 문자열에서만 작동한다는 것을 알고 있습니다. 왜 문자열에 스캐너를 사용하고 싶습니까? 스캐너는 방금 스플릿을 위해 원 스톱 상점을 만들려고합니까?

도움이 되었습니까?

해결책

그들은 본질적으로 코스를위한 말입니다.

  • Scanner 문자열을 구문 분석 해야하는 경우 다른 유형의 데이터를 꺼내는 경우를 위해 설계되었습니다. 매우 유연하지만 아마도 특정 표현식으로 구분 된 문자열 배열을 얻는 데 가장 간단한 API를 제공하지는 않습니다.
  • String.split() 그리고 Pattern.split() 후자를 수행하기위한 쉬운 구문을 제공하지만 본질적으로 그들이하는 모든 일입니다. 결과 문자열을 구문 분석하거나 특정 토큰에 따라 구분 기자를 반쯤 변경하려면 도움이되지 않습니다.
  • StringTokenizer 보다 훨씬 더 제한적입니다 String.split(), 또한 사용하기에 약간의 충실한 것입니다. 본질적으로 고정 된 하위 문자열로 구분 된 토큰을 끌어 내기 위해 설계되었습니다. 이 제한으로 인해 String.split(). (내 참조 비교 String.split() 그리고 StringTokenizer.) 또한 정규 표현식 API를 선행합니다. String.split() 부분입니다.

내 타이밍에서 주목할 것입니다 String.split() 여전히 토큰 화 될 수 있습니다 몇 밀리 초의 수천 개의 문자열 일반적인 기계에서. 또한 이점이 뛰어납니다 StringTokenizer 그것은 당신에게 출력을 문자열 배열로 제공한다는 것은 일반적으로 당신이 원하는 것입니다. 사용 Enumeration, 제공대로 StringTokenizer, 대부분은 대부분 "구문 적으로 까다로운"입니다. 이 관점에서 StringTokenizer 요즘에는 약간의 공간 낭비이며, 당신은 단지 사용할 수도 있습니다. String.split().

다른 팁

제거하여 시작합시다 StringTokenizer. 늙어 가고 정규 표현조차 지원하지 않습니다. 문서화가 나타납니다.

StringTokenizer 새로운 코드에서 사용이 권장되지만 호환성 이유로 유지되는 레거시 클래스입니다. 이 기능을 원하는 사람은 누구나 사용하는 것이 좋습니다. split 의 방법 String 아니면 그 java.util.regex 대신 패키지.

그러니 바로 버리자. 그게 떠난다 split() 그리고 Scanner. 그들의 차이점은 무엇입니까?

한가지, split() 배열을 반환하면 Foreach 루프를 쉽게 사용할 수 있습니다.

for (String token : input.split("\\s+") { ... }

Scanner 스트림처럼 만들어졌습니다.

while (myScanner.hasNext()) {
    String token = myScanner.next();
    ...
}

또는

while (myScanner.hasNextDouble()) {
    double token = myScanner.nextDouble();
    ...
}

(오히려 있습니다 큰 API, 그래서 그것은 항상 그런 단순한 것들로 제한되어 있다고 생각하지 마십시오.)

이 스트림 스타일 인터페이스는 구문 분석하기 전에 모든 입력을 가지고 있지 않거나 얻을 수없는 경우 간단한 텍스트 파일 또는 콘솔 입력을 구문 분석하는 데 유용 할 수 있습니다.

개인적으로, 내가 사용하는 것을 기억할 수있는 유일한 시간 Scanner 명령 줄에서 사용자 입력을 가져와야 할 때 학교 프로젝트를위한 것입니다. 그런 종류의 작동을 쉽게 만듭니다. 하지만 내가 있다면 String 내가 헤어지고 싶다고, 거의 쉬운 일이 아닙니다. split().

StringTokenizer는 항상 거기에있었습니다. 그것은 가장 빠르지 만, 열거와 같은 관용구는 다른 사람만큼 우아하게 보이지 않을 수 있습니다.

JDK 1.4에 분할이 존재했습니다. Tokenizer보다 느리지 만 String 클래스에서 호출 할 수 있기 때문에 사용하기 쉽습니다.

스캐너는 JDK 1.5에 왔습니다. 유명한 CS Scanf 기능 패밀리와 동등한 것을 지원하기 위해 Java API의 장기 서있는 간격을 채우는 것이 가장 유연하며.

스플릿은 느리지 만 스캐너만큼 느리지는 않습니다. StringTokenizer는 분할보다 빠릅니다. 그러나 나는 jfastparser에서 한 스피드 부스트를 얻기 위해 약간의 유연성을 거래함으로써 두 배의 속도를 얻을 수 있다는 것을 알았습니다. https://github.com/hughperkins/jfastparser

백만 개의 복식이 포함 된 문자열 테스트 :

Scanner: 10642 ms
Split: 715 ms
StringTokenizer: 544ms
JFastParser: 290ms

문자열 객체가있는 경우 토큰 화를 사용하는 경우 String 's를 사용하여 선호합니다. 나뉘다 StringTokenizer의 메소드. 파일이나 사용자의 프로그램 외부의 소스에서 텍스트 데이터를 구문 분석하는 경우 스캐너가 편리한 곳입니다.

String.split은 StringTokenizer보다 훨씬 느린 것 같습니다. Split의 유일한 장점은 토큰 배열을 얻는 것입니다. 또한 스플릿에서 정규식을 사용할 수 있습니다. org.apache.commons.lang.stringutils에는 분할 방법이 있으며, 이는 두 개의 viz보다 훨씬 빠르게 작동합니다. StringTokenizer 또는 String.split. 그러나 세 가지 모두에 대한 CPU 사용은 거의 동일합니다. 따라서 CPU 집중이 적은 방법도 필요하며 여전히 찾을 수 없습니다.

최근에 성능이 높은 상황에서 String.split ()의 나쁜 성능에 대한 실험을했습니다. 당신은 이것이 유용하다고 생각할 수 있습니다.

http://eblog.chrononsystems.com/hidden-evils-of-javas-stringsplit-and-stringr

GIST는 String.split ()가 매번 정규 표현 패턴을 컴파일하여 사전 컴파일 된 패턴 객체를 사용하고 문자열에서 직접 작동하는 경우에 비해 프로그램 속도를 느리게 할 수 있습니다.

기본 시나리오의 경우 Pattern.split ()도 제안하지만 최대 성능이 필요한 경우 (특히 테스트 한 모든 솔루션에서는 매우 느립니다) 단일 숯으로 만 분할하면 이제 내 자신의 방법을 사용합니다.

public static ArrayList<String> splitBySingleChar(final char[] s,
        final char splitChar) {
    final ArrayList<String> result = new ArrayList<String>();
    final int length = s.length;
    int offset = 0;
    int count = 0;
    for (int i = 0; i < length; i++) {
        if (s[i] == splitChar) {
            if (count > 0) {
                result.add(new String(s, offset, count));
            }
            offset = i + 1;
            count = 0;
        } else {
            count++;
        }
    }
    if (count > 0) {
        result.add(new String(s, offset, count));
    }
    return result;
}

"abc".tochararray ()를 사용하여 문자열의 숯 배열을 얻습니다. 예를 들어:

String s = "     a bb   ccc  dddd eeeee  ffffff    ggggggg ";
ArrayList<String> result = splitBySingleChar(s.toCharArray(), ' ');

중요한 차이점 중 하나는 String.split ()와 스캐너가 빈 문자열을 생성 할 수 있지만 StringTokenizer는 결코 그것을 수행하지 않는다는 것입니다.

예를 들어:

String str = "ab cd  ef";

StringTokenizer st = new StringTokenizer(str, " ");
for (int i = 0; st.hasMoreTokens(); i++) System.out.println("#" + i + ": " + st.nextToken());

String[] split = str.split(" ");
for (int i = 0; i < split.length; i++) System.out.println("#" + i + ": " + split[i]);

Scanner sc = new Scanner(str).useDelimiter(" ");
for (int i = 0; sc.hasNext(); i++) System.out.println("#" + i + ": " + sc.next());

산출:

//StringTokenizer
#0: ab
#1: cd
#2: ef
//String.split()
#0: ab
#1: cd
#2: 
#3: ef
//Scanner
#0: ab
#1: cd
#2: 
#3: ef

String.split () 및 Scanner.usedelimiter ()의 구분 기가 단순한 문자열이 아니라 정규 표현식이기 때문입니다. 위의 예제에서 Delimiter "" "" "" "" "" ""StringTokenizer처럼 행동하게 할 수 있습니다.

string.split ()는 매우 잘 작동하지만 단일 또는 이중 파이프 (|) 기호를 기반으로 아래 그림과 같이 문자열을 분할하려면 작동하지 않습니다. 이 상황에서는 StringTokenizer를 사용할 수 있습니다.

ABC | ijk

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top