Java-scanner

1. Overzicht van Scanner

In deze korte zelfstudie laten we zien hoe u de Java Scanner class - om invoer te lezen, patronen met verschillende scheidingstekens te zoeken en over te slaan.

2. Scan een bestand

Laten we eerst eens kijken hoe we een bestand kunnen lezen met Scanner.

In het volgende voorbeeld lezen we dat een bestand “Hallo Wereld”In tokens:

@Test public void whenReadFileWithScanner_thenCorrect () gooit IOException {Scanner scanner = nieuwe scanner (nieuw bestand ("test.txt")); assertTrue (scanner.hasNext ()); assertEquals ("Hallo", scanner.next ()); assertEquals ("wereld", scanner.next ()); scanner.close (); }

Merk op dat de De volgende() methode retourneert de volgende Draad token hier.

Merk ook op hoe we de scanner sluiten als we hem niet meer gebruiken.

3. Omzetten InputStream naar Draad

Vervolgens - laten we eens kijken hoe we een InputStream in een Draad gebruik maken van een Scanner:

@Test openbare leegte whenConvertInputStreamToString_thenConverted () gooit IOException {String verwachtValue = "Hallo wereld"; FileInputStream inputStream = nieuwe FileInputStream ("test.txt"); Scanner scanner = nieuwe scanner (inputStream); scanner.useDelimiter ("A"); String resultaat = scanner.next (); assertEquals (verwachte waarde, resultaat); scanner.close (); }

Net als in het vorige voorbeeld hebben we de Scanner om de hele stream van het begin tot de volgende regex "A" te tokeniseren, wat overeenkomt met de volledige invoer.

4. Scanner vs. BufferedReader

Laten we nu het verschil bespreken tussen Scanner en BufferedReader - we gebruiken over het algemeen:

  • BufferedReader wanneer we de invoer willen lezen in lijnen
  • Scanner om de invoer te lezen in tokens

In het volgende voorbeeld lezen we een bestand in regels met BufferedReader:

@Test openbare leegte whenReadUsingBufferedReader_thenCorrect () gooit IOException {String firstLine = "Hallo wereld"; String secondLine = "Hallo, John"; BufferedReader-lezer = nieuwe BufferedReader (nieuwe FileReader ("test.txt")); String resultaat = reader.readLine (); assertEquals (firstLine, resultaat); resultaat = reader.readLine (); assertEquals (secondLine, resultaat); reader.close (); }

Laten we nu gebruiken Scanner om hetzelfde bestand in tokens te lezen:

@Test public void whenReadUsingScanner_thenCorrect () gooit IOException {String firstLine = "Hallo wereld"; FileInputStream inputStream = nieuwe FileInputStream ("test.txt"); Scanner scanner = nieuwe scanner (inputStream); String resultaat = scanner.nextLine (); assertEquals (firstLine, resultaat); scanner.useDelimiter (","); assertEquals ("Hallo", scanner.next ()); assertEquals ("John", scanner.next ()); scanner.close (); }

Merk op hoe we de ScannernextLine () API - om de hele regel te lezen.

5. Scan invoer van console met Nieuwe scanner (System.in)

Vervolgens - laten we eens kijken hoe we invoer van de console kunnen lezen met een Scanner voorbeeld:

@Test openbare leegte whenReadingInputFromConsole_thenCorrect () {String input = "Hallo"; InputStream stdin = System.in; System.setIn (nieuwe ByteArrayInputStream (input.getBytes ())); Scannerscanner = nieuwe scanner (System.in); String resultaat = scanner.next (); assertEquals (invoer, resultaat); System.setIn (stdin); scanner.close (); }

Merk op dat we System.setIn (...) om invoer van de console te simuleren.

5.1. nextLine () API

Deze methode retourneert eenvoudig de string op de huidige regel:

scanner.nextLine ();

Dit leest de inhoud van de huidige regel en geeft deze terug, behalve een regelscheidingsteken aan het einde - in dit geval - het nieuwe regelteken.

Na het lezen van de inhoud, Scanner stelt zijn positie in op het begin van de volgende regel. Het belangrijke punt om te onthouden is dat de nextLine () API gebruikt het lijnscheidingsteken en verplaatst de positie van het Scanner naar de volgende regel.

Dus de volgende keer als we doorlezen Scanner we lezen vanaf het begin van de volgende regel.

5.2. volgendeInt () API

Deze methode scant het volgende token van de invoer als een int:

scanner.nextInt ();

De API leest het volgende integer-token.

In dit geval, als het volgende token een geheel getal is en na het gehele getal, er een lijnscheidingsteken is, onthoud dan altijd dat volgendeInt () zal het lijnscheidingsteken niet gebruiken. In plaats daarvan is de positie van de scanner het lijnscheidingsteken zelf.

Dus als we een reeks bewerkingen hebben, waarbij de eerste bewerking een scanner.nextInt () en dan scanner.nextLine () en als invoer als we een geheel getal opgeven en op regeleinde drukken, worden beide bewerkingen uitgevoerd.

De volgendeInt () API verbruikt het gehele getal en de nextLine () API gebruikt het lijnscheidingsteken en zal plaatsen Scanner naar het begin van de volgende regel.

6. Invoer valideren

Laten we nu eens kijken hoe we invoer kunnen valideren met een Scanner. In het volgende voorbeeld gebruiken we de Scanner methode hasNextInt () om te controleren of de invoer een geheel getal is:

@Test public void whenValidateInputUsingScanner_thenValidated () gooit IOException {String input = "2000"; InputStream stdin = System.in; System.setIn (nieuwe ByteArrayInputStream (input.getBytes ())); Scannerscanner = nieuwe scanner (System.in); boolean isIntInput = scanner.hasNextInt (); assertTrue (isIntInput); System.setIn (stdin); scanner.close (); }

7. Scan een Draad

Vervolgens - laten we eens kijken hoe we een Draad gebruik makend van Scanner:

@Test public void whenScanString_thenCorrect () gooit IOException {String input = "Hallo 1 F 3.5"; Scanner scanner = nieuwe scanner (invoer); assertEquals ("Hallo", scanner.next ()); assertEquals (1, scanner.nextInt ()); assertEquals (15, scanner.nextInt (16)); assertEquals (3.5, scanner.nextDouble (), 0.00000001); scanner.close (); }

Opmerking: de methode nextInt (16) leest het volgende token als een hexadecimaal geheel getal.

8. Zoek Patroon

Laten we nu eens kijken hoe we een Patroon gebruik makend van Scanner.

In het volgende voorbeeld gebruiken we findInLine () naar zoek naar een token dat overeenkomt met het gegeven Patroon in de gehele invoer:

@Test openbare leegte whenFindPatternUsingScanner_thenFound () gooit IOException {String verwachteValue = "wereld"; FileInputStream inputStream = nieuwe FileInputStream ("test.txt"); Scanner scanner = nieuwe scanner (inputStream); String resultaat = scanner.findInLine ("wo..d"); assertEquals (verwachte waarde, resultaat); scanner.close (); }

We kunnen ook zoeken naar een Patroon in het specifieke domein met findWithinHorizon () zoals in het volgende voorbeeld:

@Test openbare leegte whenFindPatternInHorizon_thenFound () gooit IOException {String verwachtValue = "wereld"; FileInputStream inputStream = nieuwe FileInputStream ("test.txt"); Scanner scanner = nieuwe scanner (inputStream); String resultaat = scanner.findWithinHorizon ("wo..d", 5); assertNull (resultaat); result = scanner.findWithinHorizon ("wo..d", 100); assertEquals (verwachte waarde, resultaat); scanner.close (); }

Merk op dat de zoekhorizon is gewoon het aantal tekens waarbinnen de zoekopdracht wordt uitgevoerd.

9. Overslaan Patroon

Vervolgens - laten we eens kijken hoe we een Patroon in Scanner. We kunnen tokens overslaan die overeenkomen met een specifiek patroon tijdens het lezen van de invoer met Scanner.

In het volgende voorbeeld slaan we "Hallo”Token met behulp van de Scanner methode overspringen():

@Test openbare leegte whenSkipPatternUsingScanner_thenSkipped () gooit IOException {FileInputStream inputStream = nieuwe FileInputStream ("test.txt"); Scanner scanner = nieuwe scanner (inputStream); scanner.skip (". e.lo"); assertEquals ("wereld", scanner.next ()); scanner.close (); }

10. Wijzigen Scanner Scheidingsteken

Eindelijk - laten we eens kijken hoe we het Scanner scheidingsteken. In het volgende voorbeeld wijzigen we de standaard Scanner scheidingsteken naar "O“:

@Test openbare leegte whenChangeScannerDelimiter_thenChanged () gooit IOException {String verwachtValue = "Hallo wereld"; String [] splited = verwachteValue.split ("o"); FileInputStream inputStream = nieuwe FileInputStream ("test.txt"); Scanner scanner = nieuwe scanner (inputStream); scanner.useDelimiter ("o"); assertEquals (gesplitst [0], scanner.next ()); assertEquals (gesplitst [1], scanner.next ()); assertEquals (gesplitst [2], scanner.next ()); scanner.close (); }

We kunnen ook meerdere scheidingstekens gebruiken. In het volgende voorbeeld gebruiken we beide komma's ","En streepje""Als scheidingstekens om een ​​bestand te scannen bevat"John, Adam-Tom“:

@Test public void whenReadWithScannerTwoDelimiters_thenCorrect () gooit IOException - "); assertEquals (" John ", scanner.next ()); assertEquals (" Adam ", scanner.next ()); assertEquals (" Tom ", scanner.next () ); scanner.close (); 

Merk op standaard Scanner scheidingsteken is witruimte.

11. Conclusie

In deze zelfstudie hebben we meerdere praktijkvoorbeelden besproken van het gebruik van de Java-scanner.

We hebben geleerd hoe we invoer uit een bestand, console of Draad gebruik makend van Scanner; we hebben ook geleerd hoe we een patroon kunnen vinden en overslaan met Scanner - en hoe u het Scanner scheidingsteken.

De implementatie van deze voorbeelden is te vinden op GitHub.