Scanner vs StringTokenizer vs Chaîne.Split
J'ai juste appris à propos de Java Scanner classe et maintenant je me demande comment il se compare/rivalise avec la StringTokenizer et de la Corde.Split. Je sais que le StringTokenizer et de la Corde.Split seulement le travail sur les Cordes, alors, pourquoi voudrais-je utiliser le Scanner pour une Chaîne de caractères? Est Scanner uniquement destiné à être one-stop-shopping pour la crève?
Vous devez vous connecter pour publier un commentaire.
Ils sont essentiellement de chevaux pour les cours.
Scanner
est conçu pour les cas où vous avez besoin d'analyser une chaîne de caractères, en tirant des données de différents types. Il est très souple, mais sans doute ne vous donne pas le plus simple API pour obtenir simplement un tableau de chaînes de caractères séparées par une expression particulière.String.split()
etPattern.split()
vous donner une syntaxe facile à utiliser pour faire le dernier, mais c'est essentiellement tout ce qu'ils font. Si vous souhaitez analyser le résultant de chaînes, ou de modifier le séparateur à mi-chemin par le biais de selon un pion, ils ne seront pas vous aider avec ça.StringTokenizer
est encore plus restrictive queString.split()
, et aussi un peu fiddlier à utiliser. Il est essentiellement conçu pour retirer les jetons délimité par des sous-chaînes. En raison de cette restriction, il est deux fois plus rapide queString.split()
. (Voir mon comparaison deString.split()
etStringTokenizer
.) Il est également antérieure à les expressions régulières de l'API, dontString.split()
est une partie.Vous pourrez observer de mes timings que
String.split()
peut encore marquer des milliers de chaînes de caractères dans les quelques millisecondes sur une machine typique. En outre, il a l'avantage surStringTokenizer
qu'il vous donne le résultat sous la forme d'un tableau de chaîne, ce qui est généralement ce que vous voulez. À l'aide d'unEnumeration
, comme prévu par laStringTokenizer
, est trop "syntaxiquement pointilleux" la plupart du temps. De ce point de vue,StringTokenizer
est un peu du gaspillage de l'espace de nos jours, et vous pouvez aussi bien l'utiliser justeString.split()
.StringTokenizer
toujours mon meilleur pari, carString.split()
va tout simplement à court de mémoire?StringTokenizer
accepte un flux d'entrée. Doit avoir été pensée deScanner
. Encore, je ne peux penser à une bonne utilisation deStringTokenizer
vssplit
: si vous passezreturnDelims = true
, vous obtenez des délimiteurs, que vous ne pouvez pas faire avecsplit
.Commençons par éliminer
StringTokenizer
. Il se fait vieux et n'est même pas en charge les expressions régulières. Ses états de documentation:Donc, nous allons jeter tout de suite. Qui laisse
split()
etScanner
. Quelle est la différence entre eux?Pour une chose,
split()
simplement renvoie un tableau, ce qui le rend facile à utiliser une boucle foreach:Scanner
est construit plus comme un ruisseau:ou
(Il a un assez grand API, donc ne pense pas que c'est toujours limitées à des choses simples.)
Ce volet de style de l'interface peut être utile pour l'analyse des fichiers de texte simple ou de console d'entrée, lorsque vous n'avez pas (ou ne pouvez pas faire) tous les commentaires avant de commencer à analyser.
Personnellement, la seule fois où je me souviens à l'aide de
Scanner
est pour les projets d'école, lorsque j'ai eu pour obtenir la saisie de l'utilisateur à partir de la ligne de commande. Il fait ce genre d'opération facile. Mais si j'ai unString
que je veux séparer, c'est presque une évidence pour aller avecsplit()
.Scanner
pour détecter les caractères de nouvelle ligne dans unString
. Depuis de caractères de nouvelle ligne peut varier d'une plateforme à une autre (regardezPattern
's javadoc!) et chaîne d'entrée n'est PAS garanti pour les rendre conformes àSystem.lineSeparator()
, je trouveScanner
plus adapté car il sait déjà ce que la nouvelle ligne de caractères à rechercher lors de l'appel denextLine()
. PourString.split
je vais avoir à nourrir dans la bonne regex modèle pour détecter la ligne de séparateurs, de laquelle je ne trouve pas stockée 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à. Il est le plus rapide de tous, mais l'énumération de l'idiome pourrait ne pas sembler aussi élégant que les autres.
split est venu à l'existence sur le JDK 1.4. Plus lent que le générateur de jetons, 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 la plus flexible et la remplit de longue date de l'écart sur l'API Java pour soutenir un équivalent de la célèbre Cs fonction scanf famille.
Split est lent, mais pas aussi lent que Scanner. StringTokenizer est plus rapide que de le découper. Cependant, j'ai trouvé que je pouvais obtenir le double de la vitesse, par la négociation d'une certaine souplesse, pour obtenir un speed-boost, ce que j'ai fait JFastParser https://github.com/hughperkins/jfastparser
Test sur une chaîne de caractères contenant un million de doubles:
Si vous avez une Chaîne de caractères de l'objet que vous souhaitez marquer, la faveur à l'aide de la Chaîne de split la méthode au cours d'un StringTokenizer. Si vous êtes à l'analyse des données de texte à partir d'une source à l'extérieur de votre programme, comme à partir d'un fichier, ou de l'utilisateur, c'est là un Scanner est très pratique.
Chaîne.split semble être beaucoup plus lent que StringTokenizer. Le seul avantage avec split est que vous obtenez un tableau des jetons. Aussi vous pouvez utiliser des expressions régulières dans split.
org.apache.commons.lang.StringUtils a une méthode de fractionnement qui fonctionne beaucoup plus rapide que l'un des deux viz. StringTokenizer ou Chaîne.split.
Mais l'utilisation du PROCESSEUR pour tous les trois, est presque le même. Nous avons donc aussi besoin d'une méthode qui est moins consommateur d'UC, dont je ne suis toujours pas capable de le trouver.
J'ai récemment fait quelques expériences sur la mauvaise performance de la Chaîne.split() est très sensible aux performances des situations. Vous pouvez trouver cela utile.
http://eblog.chrononsystems.com/hidden-evils-of-javas-stringsplit-and-stringr
L'essentiel est que Chaîne de caractères.split() compile un modèle d'Expression Régulière à chaque fois et peut donc ralentir votre programme, par rapport à si vous utilisez un fichier de Modèle de l'objet et de l'utiliser directement pour fonctionner sur une Chaîne.
Pour les scénarios par défaut je dirais Modèle.split (), mais si vous avez besoin d'un maximum de performance (en particulier sur Android, toutes les solutions que j'ai testé sont assez lent) et vous avez seulement besoin de diviser par un seul char que j'utilise maintenant ma propre méthode:
Utiliser "abc".toCharArray() pour obtenir le char tableau pour une Chaîne de caractères. Par exemple:
Une différence importante est que les deux Cordes.split() et le Scanner peuvent produire les cordes à vide, mais StringTokenizer est jamais.
Par exemple:
De sortie:
C'est parce que le délimiteur de Chaîne de caractères.split() et d'un Scanner.useDelimiter() n'est pas seulement une chaîne de caractères, mais une expression régulière. Nous pouvons remplacer le séparateur ", "avec" +" dans l'exemple ci-dessus pour les faire se comporter comme StringTokenizer.
Chaîne.split() fonctionne très bien, mais cela a ses limites, comme si vous vouliez de découper une chaîne comme indiqué ci-après, sur simple ou double pipe (|) symbole, il ne fonctionne pas. Dans cette situation, vous pouvez utiliser StringTokenizer.
ABC|IJK