Ce sont essentiellement des chevaux pour les cours.
Scanner
est conçu pour les cas où vous devez analyser une chaîne, extraire des données de différents types. C'est très flexible, mais sans doute ne vous donne pas l'API la plus simple pour simplement obtenir un tableau de chaînes délimitées par une expression particulière.
String.split()
et Pattern.split()
vous donner une syntaxe simple pour faire ce dernier, mais c'est essentiellement tout ce qu'ils font. Si vous souhaitez analyser les chaînes résultantes ou modifier le délimiteur à mi-chemin en fonction d'un jeton particulier, ils ne vous aideront pas.
StringTokenizer
est encore plus restrictif que String.split()
, et aussi un peu plus compliqué à utiliser. Il est essentiellement conçu pour extraire des jetons délimités par des sous-chaînes fixes. En raison de cette restriction, c'est environ deux fois plus rapide que String.split()
. (Voir ma comparaison de String.split()
etStringTokenizer
.) Il est également antérieur à l'API des expressions régulières, dont String.split()
fait partie.
Vous remarquerez d'après mes timings qui String.split()
peuvent encore symboliser des milliers de chaînes en quelques millisecondes sur une machine typique. De plus, il a l'avantage de StringTokenizer
vous donner la sortie sous forme de tableau de chaînes, ce qui est généralement ce que vous voulez. Utiliser un Enumeration
, tel que fourni par StringTokenizer
, est la plupart du temps trop «syntaxiquement difficile». De ce point de vue, StringTokenizer
c'est un peu un gaspillage d'espace de nos jours, et vous pouvez aussi bien l'utiliser String.split()
.
StringTokenizer
toujours mon meilleur pari carString.split()
je manquerai simplement de mémoire?Commençons par éliminer
StringTokenizer
. Il vieillit et ne prend même pas en charge les expressions régulières. Sa documentation indique:Alors jetons-le tout de suite. Cela laisse
split()
etScanner
. Quelle est la différence entre eux?D'une part,
split()
renvoie simplement un tableau, ce qui facilite l'utilisation d'une boucle foreach:Scanner
est construit plus comme un flux:ou
(Il a une API assez volumineuse , alors ne pensez pas qu'elle est toujours limitée à des choses aussi simples.)
Cette interface de style flux peut être utile pour analyser des fichiers texte simples ou des entrées de console, lorsque vous n'avez pas (ou ne pouvez pas obtenir) toutes les entrées avant de commencer l'analyse.
Personnellement, le seul moment où je me souviens avoir utilisé
Scanner
est pour les projets scolaires, lorsque je devais obtenir les entrées de l'utilisateur à partir de la ligne de commande. Cela facilite ce genre d'opération. Mais si j'ai unString
que je veux séparer, c'est presque une évidencesplit()
.la source
Scanner
de détecter les caractères de nouvelle ligne dans une donnéeString
. Puisque les caractères de nouvelle ligne peuvent varier d'une plate-forme à l'autre (regardezPattern
le javadoc de 's!) Et que la chaîne d'entrée n'est PAS garantie de se conformer àSystem.lineSeparator()
, je trouveScanner
plus approprié car il sait déjà quels nouveaux caractères de ligne rechercher lors de l'appelnextLine()
. CarString.split
je devrai alimenter le bon motif regex pour détecter les séparateurs de ligne, que je ne trouve pas stockés dans un emplacement standard (le mieux que je puisse faire est de le copier à partir de laScanner
source de la classe).StringTokenizer était toujours là. C'est le plus rapide de tous, mais l'idiome de type énumération peut ne pas sembler aussi élégant que les autres.
split a vu le jour sur JDK 1.4. Plus lent que tokenizer mais plus facile à utiliser, car il peut être appelé à partir de la classe String.
Scanner est venu pour être sur JDK 1.5. C'est le plus flexible et comble une lacune de longue date sur l'API Java pour prendre en charge un équivalent de la célèbre famille de fonctions scanf Cs.
la source
Si vous avez un objet String que vous souhaitez tokenize, privilégiez l'utilisation de la méthode split de String par rapport à StringTokenizer. Si vous analysez des données texte à partir d'une source extérieure à votre programme, comme à partir d'un fichier, ou de l'utilisateur, c'est là qu'un scanner est utile.
la source
Le fractionnement est lent, mais pas aussi lent que le scanner. StringTokenizer est plus rapide que split. Cependant, j'ai trouvé que je pouvais obtenir le double de la vitesse, en échangeant une certaine flexibilité, pour obtenir un gain de vitesse, ce que j'ai fait chez JFastParser https://github.com/hughperkins/jfastparser
Test sur une chaîne contenant un million de doubles:
la source
String.split semble être beaucoup plus lent que StringTokenizer. Le seul avantage de la division est que vous obtenez un tableau de jetons. Vous pouvez également utiliser toutes les expressions régulières dans split. org.apache.commons.lang.StringUtils a une méthode de fractionnement qui fonctionne beaucoup plus rapidement que l'un des deux à savoir. StringTokenizer ou String.split. Mais l'utilisation du processeur pour les trois est presque la même. Nous avons donc également besoin d'une méthode moins gourmande en CPU, que je ne suis toujours pas en mesure de trouver.
la source
J'ai récemment fait des expériences sur les mauvaises performances de String.split () dans des situations très sensibles aux performances. Cela peut vous être utile.
http://eblog.chrononsystems.com/hidden-evils-of-javas-stringsplit-and-stringr
L'essentiel est que String.split () compile un modèle d'expression régulière à chaque fois et peut donc ralentir votre programme, par rapport à si vous utilisez un objet Pattern précompilé et que vous l'utilisez directement pour opérer sur une chaîne.
la source
Pour les scénarios par défaut, je suggérerais également Pattern.split () mais si vous avez besoin de performances maximales (en particulier sur Android, toutes les solutions que j'ai testées sont assez lentes) et que vous n'avez besoin de diviser que par un seul caractère, j'utilise maintenant ma propre méthode:
Utilisez "abc" .toCharArray () pour obtenir le tableau de caractères d'une chaîne. Par exemple:
la source
Une différence importante est que String.split () et Scanner peuvent produire des chaînes vides, mais StringTokenizer ne le fait jamais.
Par exemple:
Production:
En effet, le délimiteur de String.split () et Scanner.useDelimiter () n'est pas simplement une chaîne, mais une expression régulière. Nous pouvons remplacer le délimiteur "" par "+" dans l'exemple ci-dessus pour les faire se comporter comme StringTokenizer.
la source
String.split () fonctionne très bien mais a ses propres limites, comme si vous vouliez diviser une chaîne comme indiqué ci-dessous en fonction du symbole de tube simple ou double (|), cela ne fonctionne pas. Dans cette situation, vous pouvez utiliser StringTokenizer.
ABC | IJK
la source