Członek skanera StringTokenizer przeciwko String.Split

Właśnie dowiedziałem się o klasie skanerów Java, A teraz zastanawiam się, jak się porównuje / konkuruje S. StringTokenizer i String.Split. wiem to StringTokenizer i String.Split Pracuj tylko z wierszami, więc dlaczego powinienem użyć skanera dla łańcucha? Skaner jest właśnie zaprojektowany one-stop-shopping Do podziału?
Zaproszony:

Jarosław

Potwierdzenie od:

W istocie jest konie dla kursów.


Scanner

Zaprojektowany do przypadków, gdy musisz zdemontować ciąg, wyciągając te różne typy. Jest bardzo elastyczny, ale może nie daje ci najprostnych API Dla prostego uzyskiwania gamki wierszy oddzielonych pewnym wyrazem.


String.split//

i
Pattern.split//

Daj prostą składnię do wykonywania tego ostatniego, ale to jest w rzeczywistości wszystko, co robią. Jeśli chcesz przeanalizować uzyskane linie lub zmienić separator w połowie drogi, w zależności od konkretnego markera, nie pomogą ci z nim.


StringTokenizer

jest jeszcze bardziej restrykcyjny , niż
String.split//

, A także trochę bardziej kremowy w użyciu. Jest to zasadniczo zaprojektowany do ekstrakcji markerów oddzielonych przez stałe podłoża. Z powodu tego ograniczenia jest około dwa razy szybciej niż
String.split//

. /Widzieć moje
http://www.javamex.com/tutoria ... shtml
./ Przepudza również wyrażenia regularne. API, Część, której jest
String.split//

.

Zauważysz z moich czasów
String.split//

Nadal może się stać

Tysiące linii na kilka milisekund

Na zwykłym samochodzie. Ponadto ma przewagę nad
StringTokenizer

, Co on daje wniosek w formie tablicy sznurkowej, która zwykle jest to, czego chcesz. Za pomocą
Enumeration

, Jak przewidziano
StringTokenizer

, jest też "syntactically fussy" większość czasu. Z tego punktu widzenia,
StringTokenizer

- Dzisiaj jest trochę pustych spektrum przestrzeni i możesz użyć
String.split//

.

Sławomir

Potwierdzenie od:

Zacznijmy od wyjątku
http://java.sun.com/javase/6/d ... .html
. Zgadza się i nie obsługuje nawet wyrażeń regularnych. Dokumentacja mówi ::


StringTokenizer

- Jest to przestarzała klasa, która jest przechowywana do rozważań zgodności, chociaż nie jest zalecane jego zastosowanie w nowym kodzie. Zaleca się, aby wszyscy, którzy szukają tej funkcji używanej metody
split

Z pakietu.
String

lub
java.util.regex

.

Więc rzućmy to teraz. Pozostaje tylko
http://java.sun.com/javase/6/d ... ring/
i
http://java.sun.com/javase/6/d ... .html
. Jaka jest różnica między nimi?

Najpierw,
split//

Po prostu zwraca tablicę, która upraszcza użycie cyklu foreach:


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



Scanner

Jest podniesiony jako strumień:


while /myScanner.hasNext/// {
String token = myScanner.next//;
...
}


lub


while /myScanner.hasNextDouble/// {
double token = myScanner.nextDouble//;
...
}


/On jest ładny
http://java.sun.com/javase/6/d ... mmary
, Więc nie myśl, że zawsze jest ograniczone przez takie proste rzeczy./

Ten interfejs strumieniowy może być przydatny do analizy prostych plików tekstowych lub wejścia konsoli, gdy nie masz /Lub nie może się dostać/ Wszystkie dane wejściowe przed analizą.

Osobiście pamiętam tylko raz, kiedy użyłem
Scanner

W przypadku projektów szkolnych, kiedy musiałem uzyskać niestandardowy wpis z linii poleceń. To sprawia, że ​​taka operacja jest łatwa. Ale jeśli mam
String

, czego chcę split w górę, to prawie bez problemów
split//

.

Bronisław

Potwierdzenie od:

StringTokenizer Zawsze tam był. Jest najszybszy ze wszystkich, ale wyliczenie idiomu może wyglądać tak elegancki jak inni.

split pojawił się na świetle JDK 1.4 rok. Wolniej niż tokenizer, ale łatwiej jest używać, jak nazywa się ona z klasy String.

Skaner był włączony JDK 1.5. Jest najbardziej elastyczny i wypełnia długotrwałą przestrzeń Java API Aby wspierać odpowiednik słynnej rodziny funkcji Cs scanf.

Czesław

Potwierdzenie od:

Jeśli masz obiekt string, który chcesz oznaczyć, woli korzystać z metody String
http://java.sun.com/j2se/1.5.0 ... ring/
zamiast StringTokenizer. Jeśli analizujesz dane tekstowe z źródła poza swoim programem, takie jak plik lub od użytkownika, to jest tutaj, że skaner jest przydatny.

Roman

Potwierdzenie od:

Split Działa powoli, ale nie tak powoli jak skaner. StringTokenizer szybszy niż split. Jednak odkryłem, że mogę uzyskać podwójną prędkość, sprzedając pewną elastyczność, aby uzyskać szybkość, którą zrobiłem, kiedy JFastParser
https://github.com/hughperkins/jfastparser
Testowanie na sznurku zawierającym milion podwójnych:


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

Dariusz

Potwierdzenie od:

Wygląda na to że String.split znacznie wolniej StringTokenizer. Jedyna zaleta S. split To jest to, że dostaniesz tablicę żetonów. Możesz także użyć wszelkich wyrażeń regularnych split.
org.apache.commons.lang.StringUtils ma metodę split, które pracuje znacznie szybciej niż którekolwiek z dwóch nazw. StringTokenizer lub String.split.
Ale użyj CPU Przez wszystkie trzy te same. Dlatego potrzebujemy również mniej intensywnej metody, której nadal nie mogę znaleźć.

Adam

Potwierdzenie od:

Niedawno spędziłem kilka eksperymentów o złej pracy String.split// W sytuacjach o wysokiej wrażliwości na wydajność. Możesz go znaleźć przydatne.

http://eblog.chrononsystems.co ... ringr
Dolna linia to String.split// Za każdym razem, gdy kompiluje szablon wyrażenie regularnego, a zatem może spowolnić działanie swojego programu, w porównaniu z faktem, że używasz wstępnie skompilowanego obiektu szablonu i używać go bezpośrednio do pracy ze sznurkiem.

Mieczysław

Potwierdzenie od:

Dla domyślnych skryptów sugerowałbym Pattern.split//, Ale jeśli potrzebujesz maksymalnej wydajności /Zwłaszcza na Android Wszystkie rozwiązania, które testowałem, raczej wolni/, I tylko potrzebujesz split Jeden symbol, teraz używam własnej metody:


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 &lt; length; i++/ {
if /s[i] == splitChar/ {
if /count &gt; 0/ {
result.add/new String/s, offset, count//;
}
offset = i + 1;
count = 0;
} else {
count++;
}
}
if /count &gt; 0/ {
result.add/new String/s, offset, count//;
}
return result;
}


Posługiwać się "abc".toCharArray// Aby uzyskać szereg znaków dla sznurka. Na przykład:


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


</string></string></string></string>

Zygmunt

Potwierdzenie od:

Jedną ważną różnicą jest to String.split//, a skaner może tworzyć puste struny, ale StringTokenizer nigdy tego nie robi.

Na przykład:


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///;


Wynik:


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


To dlatego, że separator String.split// i Scanner.useDelimiter// To nie jest tylko ciąg, ale wyrażenie regularne. Możemy zastąpić separator "" na " + " W powyższym przykładzie, aby się zachowali StringTokenizer.

Edward

Potwierdzenie od:

String.split// działa bardzo dobrze, ale ma swoje własne obramowania, na przykład, jeśli chcesz split Wiersz, jak pokazano poniżej, na podstawie jednej lub dwóch znaków rur / | /, to nie działa. W takim przypadku możesz użyć StringTokenizer.

ABC|IJK

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się