스캐너와 StringTokenizer 및 String.Split 및 String.Split과 어떻게 비교 / 경쟁하는지 궁금합니다.

방금 Java의 스캐너 클래스에 대해 배웠으며 이제 StringTokenizer 및 String.Split과 어떻게 비교 / 경쟁하는지 궁금합니다. StringTokenizer 및 String.Split은 문자열에서만 작동하므로 스캐너를 문자열로 사용하려는 이유는 무엇입니까? 스캐너는 분할을위한 원 스톱 쇼핑이 목적입니까?



답변

그들은 본질적으로 코스의 말입니다.

  • Scanner문자열을 구문 분석하고 다른 유형의 데이터를 가져와야하는 경우를 위해 설계되었습니다. 매우 유연하지만 특정 표현식으로 구분 된 문자열 배열을 얻는 가장 간단한 API를 제공하지는 않습니다.
  • String.split()그리고 Pattern.split()당신이 후자를 수행하기위한 쉬운 구문을 제공하지만 본질적으로 그들은 모두 할 것이 있습니다. 결과 문자열을 구문 분석하거나 특정 토큰에 따라 구분 기호를 반쯤 변경하려는 경우 도움이되지 않습니다.
  • StringTokenizer보다 제한 String.split()적이고 사용하기가 조금 더 복잡합니다. 기본적으로 고정 하위 문자열로 구분 된 토큰을 가져 오기 위해 설계되었습니다. 이 제한으로 인해 약 2 배 빠릅니다 String.split(). ( 비교를String.split()StringTokenizer 참조하십시오 .) 또한 정규 표현식 API보다 우선합니다 String.split().

필자 는 일반적인 머신에서 몇 밀리 초 안에 수천 개의 문자열을String.split() 토큰 화 할 수 있다는 타이밍을 알 수 있습니다 . 또한 출력을 문자열 배열로 제공하는 것 보다 장점 이 있습니다. 이는 일반적으로 원하는 것입니다. 에서 제공 한대로을 사용하는 것은 대부분 “구문 적으로 까다로워”입니다. 이 관점에서 요즘은 약간의 공간 낭비이며,을 사용할 수도 있습니다 .StringTokenizerEnumerationStringTokenizerStringTokenizerString.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에서 split이 존재하게되었습니다. 토크 나이저보다 느리지 만 String 클래스에서 호출 할 수 있으므로 사용하기가 더 쉽습니다.

스캐너는 JDK 1.5에있게되었습니다. 가장 유연하고 유명한 Cs scanf 함수 제품군과 동등한 기능을 지원하기 위해 Java API에서 오랜 간격을 메 웁니다.


답변

토큰 화하려는 String 객체가있는 경우 StringTokenizer보다 String의 split 메소드를 사용하는 것이 좋습니다. 파일이나 사용자와 같이 프로그램 외부의 소스에서 텍스트 데이터를 구문 분석하는 경우 검사기가 편리합니다.


답변

분할 속도는 느리지 만 스캐너만큼 느리지는 않습니다. StringTokenizer가 분할보다 빠릅니다. 그러나 JFastParser https://github.com/hughperkins/jfastparser 에서 속도 부스트를 얻기 위해 유연성을 교환하여 속도를 두 배로 늘릴 수 있음을 알았습니다.

백만 배가 포함 된 문자열 테스트 :

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


답변

String.split은 StringTokenizer보다 훨씬 느린 것 같습니다. split의 유일한 장점은 토큰 배열을 얻는 것입니다. 또한 정규식을 분할하여 사용할 수 있습니다. org.apache.commons.lang.StringUtils에는 두 개의 viz보다 훨씬 빠르게 작동하는 split 메소드가 있습니다. StringTokenizer 또는 String.split. 그러나 세 가지 모두에 대한 CPU 사용률은 거의 동일합니다. 따라서 CPU를 덜 사용하는 방법이 필요하지만 여전히 찾을 수 없습니다.


답변

나는 최근에 성능에 민감한 상황에서 String.split ()의 나쁜 성능에 대한 실험을했습니다. 이 기능이 유용 할 수 있습니다.

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

요점은 String.split ()이 매번 정규 표현식 패턴을 컴파일하므로 미리 컴파일 된 Pattern 객체를 사용하고이를 직접 사용하여 String에서 작동하는 경우에 비해 프로그램 속도가 느려질 수 있다는 것입니다.