Scanner Java hasNext () contre hasNextLine ()

1. Vue d'ensemble

La classe Scanner est un outil pratique qui peut analyser les types primitifs et les chaînes à l'aide d'expressions régulières et a été introduit dans le package java.util de Java 5.

Dans ce court tutoriel, nous parlerons de ses méthodes hasNext () et hasNextLine () . Même si ces deux méthodes peuvent sembler assez similaires au début, elles effectuent en fait des vérifications assez différentes.

Vous pouvez également en savoir plus sur la classe polyvalente Scanner dans le guide rapide ici.

2. hasNext ()

2.1. Utilisation de base

La méthode hasNext () vérifie si le Scanner a un autre jeton en entrée. Un scanner divise son entrée en jetons à l'aide d'un modèle de délimiteur, qui correspond par défaut aux espaces. Autrement dit, hasNext () vérifie l'entrée et renvoie true si elle contient un autre caractère non blanc.

Nous devons également noter quelques détails sur le délimiteur par défaut:

  • L'espace blanc comprend non seulement le caractère d'espace, mais également l'espace de tabulation ( \ t ), le saut de ligne ( \ n ) et encore plus de caractères
  • Les espaces blancs continus sont traités comme un seul délimiteur
  • Les lignes vides à la fin de l'entrée ne sont pas imprimées - c'est-à-dire que hasNext () retourne false pour les lignes vides

Jetons un coup d'œil à un exemple de la façon dont hasNext () fonctionne avec le délimiteur par défaut. Tout d'abord, nous allons préparer une chaîne d'entrée pour nous aider à explorer le résultat d'analyse de S canner :

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();

Ensuite, analysons l'entrée et imprimons le résultat:

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

Si nous exécutons le code ci-dessus, nous verrons la sortie de la console:

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

2.2. Avec délimiteur personnalisé

Jusqu'à présent, nous avons examiné hasNext () avec le délimiteur par défaut. Le scanner classe fournit un useDelimiter (modèle String) méthode qui nous permet de changer le delimiter. Une fois le délimiteur modifié, la méthode hasNext () effectuera la vérification avec le nouveau délimiteur au lieu de celui par défaut.

Voyons un autre exemple de la façon dont hasNext () et next () fonctionnent avec un délimiteur personnalisé. Nous réutiliserons l'entrée du dernier exemple.

Après le scanner analyse une correspondance symbolique la chaîne « dépendances: « , nous allons changer le séparateur à deux points ( :) afin que nous puissions analyser et extraire chaque valeur des dépendances:

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

Voyons le résultat obtenu:

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

Génial! Nous avons réussi à extraire les valeurs dans les « dépendances », cependant, il y a des problèmes de saut de ligne inattendus . Nous verrons comment les éviter dans la section suivante.

2.3. Avec regex comme délimiteur

Passons en revue la sortie dans la dernière section. Tout d'abord, nous avons remarqué qu'il y a un saut de ligne ( \ n ) avant « spring ». Nous avons changé le délimiteur en « : » après que le jeton «dependencies:» a été récupéré. Le saut de ligne après les « dépendances: » devient maintenant la partie du jeton suivant. Par conséquent, hasNext () a renvoyé true et le saut de ligne a été imprimé.

Pour la même raison, le saut de ligne après « hibernation » et la dernière ligne vide deviennent la partie du dernier jeton, donc deux lignes vides sont imprimées avec « hibernation ».

Si nous pouvons faire à la fois des deux points et des espaces comme délimiteur, alors les valeurs des «dépendances» seront correctement analysées et notre problème sera résolu. Pour y parvenir, modifions l' appel useDelimiter (":") :

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

Le « : | \\ s + » est ici une expression régulière correspondant à un seul «:» ou à un ou plusieurs espaces. Avec ce correctif, la sortie se transforme en:

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

3. hasNextLine ()

La méthode hasNextLine () vérifie s'il y a une autre ligne dans l'entrée de l' objet Scanner , que la ligne soit vide ou non.

Reprenons la même entrée. Cette fois, nous allons ajouter des numéros de ligne devant chaque ligne dans l'entrée en utilisant les méthodes hasNextLine () et nextLine () :

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

Maintenant, jetons un coup d'œil à notre sortie:

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

Comme prévu, les numéros de ligne sont imprimés et la dernière ligne vierge est là aussi.

4. Conclusion

Dans cet article, nous avons appris que Scanner de hasNextLine () méthode vérifie si une autre ligne dans l'entrée, peu importe si la ligne est vide ou non, alors que hasNext () utilise un séparateur pour vérifier un autre jeton.

Comme toujours, le code source complet des exemples est disponible à l'adresse over sur GitHub.