Scanner Java

Scanner Java

1. Vue d'ensemble

Dans ce didacticiel, nous allons illustrer comment utiliser lesJava Scanner pour lire les entrées et trouver et ignorer des modèles avec différents délimiteurs.

2. Analyser un fichier

Tout d'abord, voyons comment lire un fichier à l'aide deScanner. Dans l'exemple suivant, nous lisons un fichier contenant «Hello world» en jetons en utilisantScanner:

@Test
public void whenReadFileWithScanner_thenCorrect() throws IOException{
    Scanner scanner = new Scanner(new File("test.txt"));

    assertTrue(scanner.hasNext());
    assertEquals("Hello", scanner.next());
    assertEquals("world", scanner.next());

    scanner.close();
}

Remarque: la méthodeScannernext() renvoie le jetonString suivant.

3. ConvertirInputStream enString

Ensuite, voyons comment convertir unInputStream en unString en utilisantScanner:

@Test
public void whenConvertInputStreamToString_thenConverted()  throws IOException {
    String expectedValue = "Hello world";
    FileInputStream inputStream = new FileInputStream("test.txt");
    Scanner scanner = new Scanner(inputStream);
    scanner.useDelimiter("A");

    String result = scanner.next();
    assertEquals(expectedValue, result);

    scanner.close();
}

Remarque: Dans l'exemple précédent, nous avons trompé lesScanner pour tokeniser le flux entier du début à la prochaine regex «A» (qui correspond au début de l'entrée).

4. Scanner contre BufferedReader

Maintenant - parlons de la différence entreScanner etBufferedReader - nous utilisons généralement:

  • BufferedReader quand on veut lire l'entréeinto lines

  • Scanner pour lire l'entréeinto tokens

Dans l'exemple suivant, nous lisons un fichier en lignes à l'aide deBufferedReader:

@Test
public void whenReadUsingBufferedReader_thenCorrect()  throws IOException {
    String firstLine = "Hello world";
    String secondLine = "Hi, John";
    BufferedReader reader = new BufferedReader(new FileReader("test.txt"));

    String result = reader.readLine();
    assertEquals(firstLine, result);

    result = reader.readLine();
    assertEquals(secondLine, result);

    reader.close();
}

Maintenant, utilisonsScanner pour lire le même fichier en jetons:

@Test
public void whenReadUsingScanner_thenCorrect() throws IOException {
    String firstLine = "Hello world";
    FileInputStream inputStream = new FileInputStream("test.txt");
    Scanner scanner = new Scanner(inputStream);

    String result = scanner.nextLine();
    assertEquals(firstLine, result);

    scanner.useDelimiter(", ");
    assertEquals("Hi", scanner.next());
    assertEquals("John", scanner.next());

    scanner.close();
}

Remarque: nous pouvons également utiliser l'APIScannernextLine() pour lire la ligne entière.

5. Analyser l'entrée de la console à l'aide deNew Scanner(System.in)

Ensuite, voyons comment lire l'entrée de la console à l'aide deScanner:

@Test
public void whenReadingInputFromConsole_thenCorrect() {
    String input = "Hello";
    InputStream stdin = System.in;
    System.setIn(new ByteArrayInputStream(input.getBytes()));

    Scanner scanner = new Scanner(System.in);

    String result = scanner.next();
    assertEquals(input, result);

    System.setIn(stdin);
    scanner.close();
}

Notez que nous avons utiliséSystem.setIn(…) pour simuler certaines entrées provenant de la console.

5.1. APInextLine()

Cette méthode renvoie simplement la chaîne sur la ligne en cours:

scanner.nextLine();

Ceci lit le contenu de la ligne en cours et le renvoie, à l'exception de tout séparateur de ligne situé à la fin, dans ce cas, du caractère de nouvelle ligne.

Après avoir lu le contenu,Scanner définit sa position au début de la ligne suivante. Le point important à retenir est que lesnextLine() API consumes the line separator and moves the position of the Scanner to the next line.

Donc, la prochaine fois que nous lironsScanner, nous lirons à partir du début de la ligne suivante.

5.2. APInextInt()

Cette méthode scanne le jeton suivant de l'entrée en tant queint:

scanner.nextInt();

L'API lit le jeton entier disponible ensuite. Dans ce cas, si le jeton suivant est un entier et après l'entier, il y a un séparateur de ligne, rappelez-vous toujours quenextInt() will not consume the line separator. Instead, the position of the scanner will be the line separator itself.

Donc, si nous avons une série d'opérations, où la première opération est unscanner.nextInt() puisscanner.nextLine() et en tant qu'entrée si nous fournissons un entier et appuyez sur le saut de ligne, les deux opérations seront exécutées.

L'APInextInt() consommera l'entier et l'APInextLine() consommera le séparateur de ligne et placeraScanner au début de la ligne suivante.

6. Valider l'entrée

Voyons maintenant comment valider l'entrée à l'aide d'unScanner. Dans l'exemple suivant, nous utilisons la méthodeScannerhasNextInt() pour vérifier si l'entrée est une valeur entière:

@Test
public void whenValidateInputUsingScanner_thenValidated() throws IOException {
    String input = "2000";
    InputStream stdin = System.in;
    System.setIn(new ByteArrayInputStream(input.getBytes()));

    Scanner scanner = new Scanner(System.in);

    boolean isIntInput = scanner.hasNextInt();
    assertTrue(isIntInput);

    System.setIn(stdin);
    scanner.close();
}

7. Scanner unString

Ensuite, voyons comment analyser unString avecScanner:

@Test
public void whenScanString_thenCorrect() throws IOException {
    String input = "Hello 1 F 3.5";
    Scanner scanner = new Scanner(input);

    assertEquals("Hello", scanner.next());
    assertEquals(1, scanner.nextInt());
    assertEquals(15, scanner.nextInt(16));
    assertEquals(3.5, scanner.nextDouble(), 0.00000001);

    scanner.close();
}

Remarque: La méthodenextInt(16) lit le jeton suivant sous la forme d'une valeur entière hexadécimale.

8. RechercherPattern

Voyons maintenant comment trouver unPattern en utilisantScanner.

Dans l'exemple suivant - nous utilisonsfindInLine() àsearch for a token that matches the given Pattern dans toute l'entrée:

@Test
public void whenFindPatternUsingScanner_thenFound() throws IOException {
    String expectedValue = "world";
    FileInputStream inputStream = new FileInputStream("test.txt");
    Scanner scanner = new Scanner(inputStream);

    String result = scanner.findInLine("wo..d");
    assertEquals(expectedValue, result);

    scanner.close();
}

Nous pouvons également rechercher unPattern dans le domaine spécifique en utilisantfindWithinHorizon() comme dans l'exemple suivant:

@Test
public void whenFindPatternInHorizon_thenFound() throws IOException {
    String expectedValue = "world";
    FileInputStream inputStream = new FileInputStream("test.txt");
    Scanner scanner = new Scanner(inputStream);

    String result = scanner.findWithinHorizon("wo..d", 5);
    assertNull(result);

    result = scanner.findWithinHorizon("wo..d", 100);
    assertEquals(expectedValue, result);

    scanner.close();
}

Notez que lessearch horizon is simply the number of characters dans lesquels la recherche est effectuée.

9. IgnorerPattern

Ensuite, voyons comment ignorer unPattern dansScanner. Nous pouvons ignorer les jetons qui correspondent à un modèle spécifique lors de la lecture de l'entrée en utilisantScanner.

Dans l'exemple suivant, nous ignorons le jeton «Hello» à l'aide de la méthodeScannerskip():

@Test
public void whenSkipPatternUsingScanner_thenSkipped() throws IOException {
    FileInputStream inputStream = new FileInputStream("test.txt");
    Scanner scanner = new Scanner(inputStream);

    scanner.skip(".e.lo");

    assertEquals("world", scanner.next());

    scanner.close();
}

10. Changer le délimiteurScanner

Enfin, voyons comment changer le délimiteurScanner. Dans l'exemple suivant, nous modifions le séparateur par défautScanner en «o»:

@Test
public void whenChangeScannerDelimiter_thenChanged() throws IOException {
    String expectedValue = "Hello world";
    String[] splited = expectedValue.split("o");

    FileInputStream inputStream = new FileInputStream("test.txt");
    Scanner scanner = new Scanner(inputStream);
    scanner.useDelimiter("o");

    assertEquals(splited[0], scanner.next());
    assertEquals(splited[1], scanner.next());
    assertEquals(splited[2], scanner.next());

    scanner.close();
}

Nous pouvons également utiliser plusieurs délimiteurs. Dans l'exemple suivant - nous utilisons à la fois la virgule «,» et le tiret «» comme délimiteurs pour analyser un fichier contenant «John,Adam-Tom»:

@Test
public void whenReadWithScannerTwoDelimiters_thenCorrect()
  throws IOException {
    Scanner scanner = new Scanner(new File("test.txt"));
    scanner.useDelimiter(",|-");

    assertEquals("John", scanner.next());
    assertEquals("Adam", scanner.next());
    assertEquals("Tom", scanner.next());

    scanner.close();
}

Remarque: Lesdefault Scanner delimiter sont des espaces.

11. Conclusion

Dans ce didacticiel, nous avons passé en revue plusieurs exemples concrets d'utilisation desJava Scanner.

Nous avons appris à lire l'entrée d'un fichier, d'une console ou deString en utilisantScanner; nous avons également appris comment trouver et ignorer un motif en utilisantScanner - ainsi que comment changer le délimiteurScanner.

La mise en œuvre de ces exemples peut être trouvéeover on GitHub - il s'agit d'un projet basé sur Maven, il devrait donc être facile à importer et à exécuter tel quel.