Sie sind im Wesentlichen Pferde für Kurse.
Scanner
wurde für Fälle entwickelt, in denen Sie eine Zeichenfolge analysieren und Daten verschiedener Typen abrufen müssen. Es ist sehr flexibel, bietet Ihnen aber wahrscheinlich nicht die einfachste API, um einfach ein Array von Zeichenfolgen abzurufen, die durch einen bestimmten Ausdruck begrenzt sind.
String.split()
und Pattern.split()
geben Sie eine einfache Syntax für Letzteres, aber das ist im Wesentlichen alles, was sie tun. Wenn Sie die resultierenden Zeichenfolgen analysieren oder das Trennzeichen je nach Token in der Mitte ändern möchten, helfen sie Ihnen dabei nicht weiter.
StringTokenizer
ist noch restriktiver als String.split()
und auch etwas umständlicher zu bedienen. Es ist im Wesentlichen zum Herausziehen von Token vorgesehen, die durch feste Teilzeichenfolgen begrenzt sind. Aufgrund dieser Einschränkung ist es ungefähr doppelt so schnell wie String.split()
. (Siehe meinen Vergleich von String.split()
undStringTokenizer
.) Es ist auch älter als die API für reguläre Ausdrücke, zu der auch String.split()
ein Teil gehört.
Sie werden String.split()
anhand meiner Timings feststellen, dass auf einem typischen Computer in wenigen Millisekunden immer noch Tausende von Zeichenfolgen als Token verwendet werden können . Darüber hinaus hat es den Vorteil, StringTokenizer
dass Sie die Ausgabe als String-Array erhalten, was normalerweise gewünscht wird. Die Verwendung von Enumeration
, wie von bereitgestellt StringTokenizer
, ist die meiste Zeit zu "syntaktisch pingelig". Unter diesem Gesichtspunkt StringTokenizer
ist es heutzutage eine Verschwendung von Platz, und Sie können es auch einfach verwenden String.split()
.
StringTokenizer
immer noch meine beste Wahl, weilString.split()
mir einfach der Speicher ausgeht?Beginnen wir mit der Beseitigung
StringTokenizer
. Es wird alt und unterstützt nicht einmal reguläre Ausdrücke. In der Dokumentation heißt es:Also werfen wir es sofort raus. Das lässt
split()
undScanner
. Was ist der Unterschied zwischen ihnen?Zum einen wird
split()
einfach ein Array zurückgegeben, wodurch die Verwendung einer foreach-Schleife vereinfacht wird:Scanner
ist eher wie ein Stream aufgebaut:oder
(Es hat eine ziemlich große API , denken Sie also nicht, dass es immer auf so einfache Dinge beschränkt ist.)
Diese Benutzeroberfläche im Stream-Stil kann nützlich sein, um einfache Textdateien oder Konsoleneingaben zu analysieren, wenn Sie nicht alle Eingaben haben (oder nicht erhalten können), bevor Sie mit dem Parsen beginnen.
Persönlich kann ich mich
Scanner
nur an Schulprojekte erinnern , bei denen ich Benutzereingaben über die Befehlszeile erhalten musste. Es macht diese Art der Bedienung einfach. Aber wenn ich eine habeString
, die ich aufteilen möchte, ist das fast ein Kinderspielsplit()
.quelle
Scanner
neue Zeilenzeichen in einer bestimmten erkanntString
. Da neue Zeilenzeichen von Plattform zu Plattform variieren können (siehePattern
Javadoc!) Und die Eingabe der Zeichenfolge NICHT garantiert istSystem.lineSeparator()
, finde ich sieScanner
besser geeignet, da sie bereits weiß, nach welchen neuen Zeilenzeichen beim Aufrufen zu suchen istnextLine()
. DennString.split
ich muss das richtige Regex-Muster eingeben, um Zeilentrennzeichen zu erkennen, die an keinem Standardspeicherort gespeichert sind (das Beste, was ich tun kann, ist, sie aus derScanner
Quelle der Klasse zu kopieren ).StringTokenizer war immer da. Es ist das schnellste von allen, aber die aufzählungsähnliche Redewendung sieht möglicherweise nicht so elegant aus wie die anderen.
Split entstand auf JDK 1.4. Langsamer als Tokenizer, aber einfacher zu verwenden, da es über die String-Klasse aufgerufen werden kann.
Der Scanner wurde auf JDK 1.5 ausgeführt. Es ist das flexibelste und füllt eine lange Lücke in der Java-API, um ein Äquivalent der berühmten Cs scanf-Funktionsfamilie zu unterstützen.
quelle
Wenn Sie ein String-Objekt haben, das Sie tokenisieren möchten, bevorzugen Sie die Verwendung der Split- Methode von String gegenüber einem StringTokenizer. Wenn Sie Textdaten aus einer Quelle außerhalb Ihres Programms analysieren, z. B. aus einer Datei oder vom Benutzer, ist ein Scanner hilfreich.
quelle
Split ist langsam, aber nicht so langsam wie Scanner. StringTokenizer ist schneller als Split. Ich stellte jedoch fest, dass ich durch den Handel mit etwas Flexibilität die doppelte Geschwindigkeit erreichen konnte, um einen Geschwindigkeitsschub zu erzielen, wie ich es bei JFastParser https://github.com/hughperkins/jfastparser getan habe
Testen an einer Zeichenfolge mit einer Million Doppel:
quelle
String.split scheint viel langsamer zu sein als StringTokenizer. Der einzige Vorteil bei Split ist, dass Sie eine Reihe von Token erhalten. Sie können auch beliebige reguläre Ausdrücke in Split verwenden. org.apache.commons.lang.StringUtils verfügt über eine Split-Methode, die viel schneller arbeitet als jede der beiden Methoden. StringTokenizer oder String.split. Die CPU-Auslastung ist jedoch für alle drei nahezu gleich. Wir brauchen also auch eine Methode, die weniger CPU-intensiv ist und die ich immer noch nicht finden kann.
quelle
Ich habe kürzlich einige Experimente über die schlechte Leistung von String.split () in sehr leistungsempfindlichen Situationen durchgeführt. Sie können dies nützlich finden.
http://eblog.chrononsystems.com/hidden-evils-of-javas-stringsplit-and-stringr
Das Wesentliche ist, dass String.split () jedes Mal ein Muster für reguläre Ausdrücke kompiliert und somit Ihr Programm verlangsamen kann, verglichen mit der Verwendung eines vorkompilierten Musterobjekts und der direkten Verwendung für die Bearbeitung eines Strings.
quelle
Für die Standardszenarien würde ich auch Pattern.split () vorschlagen, aber wenn Sie maximale Leistung benötigen (insbesondere unter Android sind alle von mir getesteten Lösungen ziemlich langsam) und Sie nur durch ein einziges Zeichen teilen müssen, verwende ich jetzt meine eigene Methode:
Verwenden Sie "abc" .toCharArray (), um das char-Array für einen String abzurufen. Beispielsweise:
quelle
Ein wichtiger Unterschied besteht darin, dass sowohl String.split () als auch Scanner leere Zeichenfolgen erzeugen können, StringTokenizer jedoch niemals.
Beispielsweise:
Ausgabe:
Dies liegt daran, dass das Trennzeichen für String.split () und Scanner.useDelimiter () nicht nur eine Zeichenfolge, sondern ein regulärer Ausdruck ist. Wir können das Trennzeichen "" im obigen Beispiel durch "+" ersetzen, damit sie sich wie StringTokenizer verhalten.
quelle
String.split () funktioniert sehr gut, hat aber seine eigenen Grenzen. Wenn Sie beispielsweise einen String wie unten gezeigt anhand des Single- oder Double-Pipe-Symbols (|) teilen möchten, funktioniert dies nicht. In dieser Situation können Sie StringTokenizer verwenden.
ABC | IJK
quelle