Je viens de découvrir la classe Scanner de Java et je me demande maintenant comment elle se compare à StringTokenizer et String.Split. Je sais que StringTokenizer et String.Split ne fonctionnent que sur les chaînes de caractères, alors pourquoi voudrais-je utiliser Scanner pour une chaîne de caractères ? Le Scanner est-il simplement destiné à être un guichet unique pour le fractionnement ?
Réponses
Trop de publicités?Ils sont essentiellement des chevaux de course.
Scanner
est conçu pour les cas où vous devez analyser une chaîne de caractères, en extrayant des données de différents types. Elle est très flexible, mais on peut dire qu'elle ne vous offre pas l'API la plus simple pour obtenir simplement un tableau de chaînes de caractères délimitées par une expression particulière.
String.split()
yPattern.split()
vous donnent une syntaxe facile pour faire cette dernière, mais c'est essentiellement tout ce qu'ils font. Si vous voulez analyser les chaînes de caractères résultantes, ou changer le délimiteur à mi-chemin en fonction d'un jeton particulier, ils ne vous aideront pas à le faire.
StringTokenizer
est encore plus restrictive queString.split()
et aussi un peu plus difficile à utiliser. Il est essentiellement conçu pour extraire des tokens délimités par des sous-chaînes fixes. À cause de cette restriction, il est environ deux fois plus rapide queString.split()
. (Voir mon comparaison deString.split()
yStringTokenizer
.) Elle est également antérieure à l'API des expressions régulières, dontString.split()
en fait partie.
Vous noterez dans mes chronologies que String.split()
peut toujours tokeniser des milliers de chaînes de caractères en quelques millisecondes sur une machine typique. En outre, il présente l'avantage de StringTokenizer
qu'il vous donne la sortie comme un tableau de chaînes, ce qui est généralement ce que vous voulez. L'utilisation d'un Enumeration
conformément aux dispositions de la StringTokenizer
est trop "syntaxiquement difficile" la plupart du temps. De ce point de vue, StringTokenizer
est un peu un gaspillage d'espace de nos jours, et vous pouvez tout aussi bien utiliser la fonction String.split()
.
Commençons par éliminer StringTokenizer
. Il se fait vieux et ne supporte même pas les expressions régulières. Sa documentation indique :
StringTokenizer
est une ancienne classe qui est conservée pour des raisons de compatibilité, bien que son utilisation soit déconseillée dans le nouveau code. Il est recommandé à toute personne recherchant cette fonctionnalité d'utiliser la classesplit
méthode deString
ou lejava.util.regex
à la place.
Alors jetons-le tout de suite. Cela laisse split()
y Scanner
. Quelle est la différence entre eux ?
D'abord, split()
renvoie simplement un tableau, ce qui permet d'utiliser facilement une boucle foreach :
for (String token : input.split("\\s+") { ... }
Scanner
est construit plus comme un ruisseau :
while (myScanner.hasNext()) {
String token = myScanner.next();
...
}
ou
while (myScanner.hasNextDouble()) {
double token = myScanner.nextDouble();
...
}
(Il a un plutôt grande API Ne croyez donc pas qu'elle se limite toujours à des choses aussi simples).
Cette interface de type flux peut être utile pour analyser des fichiers texte simples ou l'entrée de la console, lorsque vous n'avez pas (ou ne pouvez pas obtenir) toute l'entrée avant de commencer l'analyse.
Personnellement, la seule fois où je me rappelle avoir utilisé Scanner
c'est pour des projets scolaires, lorsque je devais obtenir des entrées utilisateur à partir de la ligne de commande. Il rend ce genre d'opération facile. Mais si j'ai un String
que je veux diviser, c'est presque une évidence d'aller avec split()
.
StringTokenizer était toujours là. C'est le plus rapide de tous, mais l'idiome de type énumération n'est peut-être pas aussi élégant que les autres.
split a vu le jour avec le JDK 1.4. Plus lent que tokenizer mais plus facile à utiliser, puisqu'il est appelable depuis la classe String.
Scanner est apparu avec le JDK 1.5. C'est la plus flexible et elle comble une lacune de longue date de l'API Java en prenant en charge un équivalent de la célèbre famille de fonctions scanf de Cs.
Si vous avez un objet String que vous voulez tokeniser, privilégiez l'utilisation de la méthode String. divisé sur un StringTokenizer. Si vous devez analyser des données textuelles provenant d'une source extérieure à votre programme, comme un fichier, ou de l'utilisateur, c'est là qu'un Scanner est utile.
J'ai récemment fait quelques expériences sur les mauvaises performances de String.split() dans des situations très sensibles aux performances. Vous pouvez trouver cela utile.
http://eblog.chrononsystems.com/hidden-evils-of-javas-stringsplit-and-stringr
L'essentiel est que String.split() compile un motif d'expression régulière à chaque fois et peut donc ralentir votre programme, par rapport à l'utilisation d'un objet motif précompilé et à son utilisation directe pour opérer sur une chaîne.