Java Scanner hasNext () vs. hasNextLine ()

1. Übersicht

Die Scanner- Klasse ist ein praktisches Tool, mit dem primitive Typen und Zeichenfolgen mithilfe regulärer Ausdrücke analysiert werden können. Sie wurde in Java 5 in das Paket java.util eingeführt .

In diesem kurzen Tutorial werden wir über die Methoden hasNext () und hasNextLine () sprechen . Obwohl diese beiden Methoden auf den ersten Blick ziemlich ähnlich aussehen, führen sie tatsächlich ganz unterschiedliche Überprüfungen durch.

Weitere Informationen zur vielseitigen Scannerklasse finden Sie in der Kurzanleitung hier.

2. hasNext ()

2.1. Grundlegende Verwendung

Die Methode hasNext () prüft, ob der Scanner ein anderes Token in seiner Eingabe hat. Ein Scanner unterteilt seine Eingabe in Token mithilfe eines Begrenzungsmusters, das standardmäßig mit Leerzeichen übereinstimmt. Das heißt, hasNext () überprüft die Eingabe und gibt true zurück , wenn es ein anderes Nicht-Leerzeichen enthält.

Wir sollten auch einige Details zum Standardtrennzeichen beachten:

  • Whitespace enthält nicht nur das Leerzeichen, sondern auch das Tabulatorzeichen ( \ t ), den Zeilenvorschub ( \ n ) und noch mehr Zeichen
  • Fortlaufende Leerzeichen werden als einzelnes Trennzeichen behandelt
  • Die Leerzeilen am Ende der Eingabe werden nicht gedruckt. Das heißt, hasNext () gibt für Leerzeilen false zurück

Schauen wir uns ein Beispiel an, wie hasNext () mit dem Standardtrennzeichen funktioniert. Zuerst bereiten wir eine Eingabezeichenfolge vor, um das Analyseergebnis von S canner zu untersuchen :

String INPUT = new StringBuilder() .append("magic\tproject\n") .append(" database: oracle\n") .append("dependencies:\n") .append("spring:foo:bar\n") .append("\n") // Note that the input ends with a blank line .toString();

Als nächstes analysieren wir die Eingabe und drucken das Ergebnis:

Scanner scanner = new Scanner(INPUT); while (scanner.hasNext()) { log.info(scanner.next()); } log.info("--------OUTPUT--END---------") 

Wenn wir den obigen Code ausführen, wird die Konsolenausgabe angezeigt:

[DEMO]magic [DEMO]project [DEMO]database: [DEMO]oracle [DEMO]dependencies: [DEMO]spring:foo:bar [DEMO]--------OUTPUT--END--------- 

2.2. Mit benutzerdefiniertem Trennzeichen

Bisher haben wir uns hasNext () mit dem Standardtrennzeichen angesehen. Die Scanner - Klasse stellt eine useDelimiter (String - Muster) Methode , die uns das Trennzeichen zu ändern. Sobald das Trennzeichen geändert wurde, führt die Methode hasNext () die Prüfung mit dem neuen Trennzeichen anstelle des Standardtrennzeichens durch.

Sehen wir uns ein weiteres Beispiel an, wie hasNext () und next () mit einem benutzerdefinierten Trennzeichen arbeiten. Wir werden die Eingabe aus dem letzten Beispiel wiederverwenden.

Nachdem der Scanner der Zeichenfolge „eine Token Anpassung analysiert Abhängigkeiten: „werden wir das Trennzeichen einen Doppelpunkt ändern ( :) , so dass wir jeden Wert der Abhängigkeiten analysieren und extrahieren:

while (scanner.hasNext()) { String token = scanner.next(); if ("dependencies:".equals(token)) { scanner.useDelimiter(":"); } log.info(token); } log.info("--------OUTPUT--END---------");

Lassen Sie uns die resultierende Ausgabe sehen:

[DEMO]magic [DEMO]project [DEMO]database: [DEMO]oracle [DEMO]dependencies: [DEMO] spring [DEMO]foo [DEMO]bar [DEMO]--------OUTPUT--END---------

Großartig! Wir haben die Werte in „ Abhängigkeiten “ erfolgreich extrahiert , es gibt jedoch einige unerwartete Zeilenumbruchprobleme . Wir werden im nächsten Abschnitt sehen, wie Sie diese vermeiden können.

2.3. Mit Regex als Trennzeichen

Lassen Sie uns die Ausgabe im letzten Abschnitt überprüfen. Zuerst haben wir festgestellt, dass es vor „ Frühling “ einen Zeilenumbruch ( \ n ) gibt . Wir haben das Trennzeichen in " : " geändert, nachdem das Token "Abhängigkeiten:" abgerufen wurde. Der Zeilenumbruch nach den " Abhängigkeiten: " wird jetzt Teil des nächsten Tokens. Daher hasNext () zurückgegeben wahr und der Zeilenumbruch wurde ausgedruckt.

Aus dem gleichen Grund werden der Zeilenvorschub nach dem Ruhezustand und die letzte Leerzeile Teil des letzten Tokens, sodass zwei Leerzeilen zusammen mit dem Ruhezustand ausgedruckt werden .

Wenn wir sowohl Doppelpunkt als auch Leerzeichen als Trennzeichen festlegen können, werden die Werte für "Abhängigkeiten" korrekt analysiert und unser Problem wird gelöst. Um dies zu erreichen, ändern wir den Aufruf von useDelimiter (":") :

scanner.useDelimiter(":|\\s+"); 

Das " : | \\ s + " hier ist ein regulärer Ausdruck, der einem einzelnen ":" oder einem oder mehreren Leerzeichen entspricht. Mit diesem Fix wird die Ausgabe in:

[DEMO]magic [DEMO]project [DEMO]database: [DEMO]oracle [DEMO]dependencies: [DEMO]spring [DEMO]foo [DEMO]bar [DEMO]--------OUTPUT--END---------

3. hasNextLine ()

Die hasNextLine () Methode überprüft , um zu sehen , ob es in dem Eingang des Leitung eine andere Scanner Objekts, egal ob die Zeile leer ist oder nicht.

Nehmen wir die gleiche Eingabe noch einmal. Dieses Mal fügen wir Zeilennummern vor jeder Zeile in der Eingabe mit den Methoden hasNextLine () und nextLine () hinzu :

int i = 0; while (scanner.hasNextLine())  log.info(String.format("%d log.info("--------OUTPUT--END---------");

Schauen wir uns nun unsere Ausgabe an:

[DEMO]1|magic project [DEMO]2| database: oracle [DEMO]3|dependencies: [DEMO]4|spring:foo:bar [DEMO]5| [DEMO]--------OUTPUT--END---------

Wie erwartet werden die Zeilennummern gedruckt und die letzte leere Zeile ist auch da.

4. Fazit

In diesem Artikel haben wir erfahren, dass die hasNextLine () -Methode von Scanner prüft, ob die Eingabe eine andere Zeile enthält, unabhängig davon, ob die Zeile leer ist oder nicht, während hasNext () ein Trennzeichen verwendet, um nach einem anderen Token zu suchen .

Wie immer ist der vollständige Quellcode für die Beispiele auf GitHub verfügbar.