Java-scanner hasNext () versus hasNextLine ()

1. Overzicht

De Scanner class is een handige tool die primitieve typen en strings kan ontleden met behulp van reguliere expressies en werd geïntroduceerd in de java.util pakket in Java 5.

In deze korte tutorial zullen we het erover hebben hasNext () en hasNextLine () methoden. Hoewel deze twee methoden er in eerste instantie misschien hetzelfde uitzien, voeren ze eigenlijk heel verschillende controles uit.

U kunt hier ook meer lezen over de veelzijdige Scanner-klasse in de beknopte handleiding.

2. hasNext ()

2.1. Basisgebruik

De hasNext () methode controleert of het Scanner heeft een ander token in zijn invoer. EEN Scanner breekt zijn invoer in tokens met behulp van een scheidingstekenpatroon, dat standaard overeenkomt met witruimte. Dat is, hasNext () controleert de invoer en retourneert waar als het een ander niet-witruimte-teken heeft.

We moeten ook een paar details opmerken over het standaard scheidingsteken:

  • Witruimte omvat niet alleen de spatie, maar ook de tabruimte (\ t), line feed (\ n), en zelfs meer karakters
  • Doorlopende witruimtetekens worden behandeld als een enkel scheidingsteken
  • De lege regels aan het einde van de invoer worden niet afgedrukt, dat wil zeggen, hasNext () geeft terug false voor lege regels

Laten we een voorbeeld bekijken van hoe hasNext () werkt met het standaard scheidingsteken. Eerst bereiden we een invoertekenreeks voor om ons te helpen S te verkennenconservenfabrikantHet resultaat van het parseren:

String INPUT = nieuwe StringBuilder () .append ("magic \ tproject \ n") .append ("database: oracle \ n") .append ("afhankelijkheden: \ n") .append ("spring: foo: bar \ n ") .append (" \ n ") // Merk op dat de invoer eindigt met een lege regel .toString ();

Laten we vervolgens de invoer analyseren en het resultaat afdrukken:

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

Als we de bovenstaande code uitvoeren, zien we de console-uitvoer:

[DEMO] magisch [DEMO] project [DEMO] database: [DEMO] oracle [DEMO] afhankelijkheden: [DEMO] spring: foo: bar [DEMO] -------- OUTPUT - END ----- ---- 

2.2. Met aangepast scheidingsteken

Tot nu toe hebben we gekeken naar hasNext () met het standaard scheidingsteken. De Scanner klasse verschaft een useDelimiter (String patroon) methode waarmee we het scheidingsteken kunnen wijzigen. Zodra het scheidingsteken is gewijzigd, wordt het hasNext () methode zal de controle uitvoeren met het nieuwe scheidingsteken in plaats van het standaard scheidingsteken.

Laten we nog een voorbeeld bekijken van hoe hasNext () en De volgende() werken met een aangepast scheidingsteken. We zullen de invoer uit het laatste voorbeeld hergebruiken.

Nadat de scanner een token heeft geparseerd dat overeenkomt met de tekenreeks "afhankelijkheden:", We veranderen het scheidingsteken in een dubbele punt ( : ) zodat we elke waarde van de afhankelijkheden kunnen ontleden en extraheren:

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

Laten we de resulterende uitvoer bekijken:

[DEMO] magisch [DEMO] project [DEMO] database: [DEMO] oracle [DEMO] afhankelijkheden: [DEMO] lente [DEMO] foo [DEMO] balk [DEMO] -------- OUTPUT - END- --------

Super goed! We hebben met succes de waarden geëxtraheerd in "afhankelijkheden“Er zijn er echter een paar onverwachte line-break-problemen. In de volgende sectie zullen we zien hoe we deze kunnen vermijden.

2.3. Met regex als scheidingsteken

Laten we de uitvoer in de laatste sectie bekijken. Ten eerste hebben we gemerkt dat er een regeleinde is (\ n) voordat "voorjaar“. We hebben het scheidingsteken gewijzigd in ':" na de "Afhankelijkheden:" token is opgehaald. Het regeleinde na de "afhankelijkheden:”Wordt nu het deel van het volgende token. Daarom hasNext () keerde terug waar en het regeleinde werd afgedrukt.

Om dezelfde reden wordt de regeldoorvoer na "overwinteren"En de laatste lege regel worden het deel van de laatste token, dus worden twee lege regels afgedrukt samen met"overwinteren“.

Als we zowel een dubbele punt als een spatie als scheidingsteken kunnen maken, worden de "afhankelijkheden" -waarden correct geparseerd en wordt ons probleem opgelost. Om dat te bereiken, veranderen we de useDelimiter (":") bellen:

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

De ": | \ s +”Hier is een reguliere expressie die overeenkomt met een enkele“: ”of een of meer witruimtetekens. Met deze oplossing verandert de uitvoer in:

[DEMO] magisch [DEMO] project [DEMO] database: [DEMO] oracle [DEMO] afhankelijkheden: [DEMO] lente [DEMO] foo [DEMO] balk [DEMO] -------- OUTPUT - END- --------

3. hasNextLine ()

De hasNextLine () methode controleert of er een andere regel in de invoer van de Scanner object, ongeacht of de regel leeg is of niet.

Laten we dezelfde invoer nog een keer nemen. Deze keer voegen we regelnummers toe voor elke regel in de invoer met hasNextLine () en nextLine () methoden:

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

Laten we nu eens kijken naar onze output:

[DEMO] 1 | magisch project [DEMO] 2 | database: oracle [DEMO] 3 | afhankelijkheden: [DEMO] 4 | lente: foo: bar [DEMO] 5 | [DEMO] -------- UITGANG - EINDE ---------

Zoals we hadden verwacht, worden de regelnummers afgedrukt en is de laatste lege regel er ook.

4. Conclusie

In dit artikel hebben we dat geleerd Scanner‘S hasNextLine () methode controleert of er een andere regel in de invoer staat, ongeacht of de regel leeg is of niet, while hasNext () gebruikt een scheidingsteken om te controleren op een ander token.

Zoals altijd is de volledige broncode voor de voorbeelden beschikbaar op GitHub.