2016-05-28 1 views
1

Je possède ce code:Pourquoi StringTokenizer.hasMoreTokens renvoie-t-il true lorsqu'il ne l'est pas?

StringTokenizer st = new StringTokenizer (line, String.valueOf(delimiter)); 

labels.add("Time"); 

int currentCol = 1;             
while (st.hasMoreTokens()) 
{ 
    st.nextToken(); 
    labels.add(new String("c" + currentCol++));         
} 

delimiter est ; et la ligne est 0.6245. Pourquoi est-ce que je me retrouve avec un ArrayListlabels qui a son deuxième élément c1? Alors que la documentation dit:

Teste s'il y a plus de jetons disponibles à partir de cette chaîne de jetons. Si cette méthode renvoie true, un appel ultérieur à nextToken sans argument retournera un jeton.

Retours:

vrai si et seulement s'il y a au moins un jeton dans la chaîne après la position actuelle; false sinon.

Puisque la valeur: 0.6245 ne peut pas être divisé par delimiter ; pourquoi serait-hasMoreTokens() retour true?

EDIT:

Je comprends maintenant pourquoi exécuter au moins une fois de boucle obtenir while. C'est parce que c'est ainsi que fonctionne le StringTokenizer. Plutôt que le split normal que je suis habitué à où je peux accéder à n'importe quelle position du array résultant, ici la seule manière d'accéder aux éléments est avec la méthode nextElement(). Ce qui signifie que même s'il n'y a qu'un seul élément dans le StringTokenizer, il retournera toujours true de hasMoreTokens().

La raison pour laquelle je m'interroge sur StringTokenizer qui est ce que j'ai appris une classe d'héritage est que j'examine un ancien code que je suis sur le point de réutiliser.

+0

Imprimez les jetons et vérifiez si les valeurs sont correctes. –

+1

Vous devriez lire un peu plus de la documentation: * "Un jeton est une séquence maximale de caractères consécutifs qui ne sont pas des délimiteurs" *. Donc, si le délimiteur ne peut pas être trouvé, alors toute la chaîne fournie est un jeton. (La même chose s'applique à 'String # split', au cas où vous aimeriez l'utiliser à la place) – Tom

+0

Aussi _StringTokenizer est une classe héritée qui est conservée pour * raisons de compatibilité bien que son utilisation soit déconseillée dans le nouveau code.Il est * recommandé que Quelqu'un qui recherche cette fonctionnalité utilise la méthode split * à la place du paquet java.util.regex._ – zencv

Répondre

1

Votre problème est que vous ajoutez un élément sur votre liste en dehors de votre boucle:

labels.add("Time"); 

Vous avez juste un jeton après la Tokenize fonctionne. En effet, lorsque vous tokenize une chaîne qui n'a pas le courant delimiter vous avez un seul élément, donc si votre chaîne est 0.6245 comprendre comme des jetons que (pour votre delimiter):

First token: 0.6245 
Second token: nothing 

Il est comme si elle était : 0.6245;

l'intérieur de votre boucle, vous ajoutez une autre chose à votre liste de tableau:

labels.add(new String("c" + currentCol++)); 

Puisque vous currentCol comme initialisé 1 et le while courrez j Une fois qu'il aura le c1 comme valeur sur le deuxième élément de votre liste (rappelez-vous, vous en avez ajouté un avant)

Je ne sais pas ce que vous essayez d'atteindre.Mais il semble que vous voulez quelque chose comme:

StringTokenizer st = new StringTokenizer (line, String.valueOf(delimiter)); 

//Don't add this: 
//labels.add("Time"); 

int currentCol = 1;             
while (st.hasMoreTokens()) 
{ 
    String someThing = st.nextToken(); 
    labels.add(new String("Current token:" + someThing 
        + "\n currentCol: " + currentCol++));         
} 
+0

Vous avez entièrement raison et merci pour votre réponse. Je me demandais juste pourquoi 'hasMoreTokens' retournait vrai si, comme vous l'avez dit, le second jeton n'est rien? Ce n'est pas une boucle do-while ... et la condition n'a pas été remplie. –

+0

Ce n'est pas qu'il ne retourne rien, Quand il entre dans la boucle while il est sur la première position. Mais votre liste 'labels' dans votre code a déjà un élément, donc le' c1' sur la deuxième position. Lorsque vous appelez 'st.nextToken()' seulement, alors il se déplace vers le second élément qui n'existe pas, donc il quitte le temps après la fin. –

+0

Mais si 'StringTokenizer' n'a qu'un seul élément, pourquoi' st.hasMoreTokens() 'retourne' true'? Peut-être que c'est le comportement standard mais ça n'a pas de sens pour moi, s'il n'y a qu'un jeton alors il n'y a plus de jetons ... En tout cas je vous donne +1 pour essayer de m'expliquer cela. –

2

0,6245 lui-même est un jeton si vous ne disposez pas d'un delimiter. Si vous aviez quelque chose comme ceci "0,6245; 0,987" alors il a 2 jetons. À moins que votre ligne a un espace vide ou une valeur nulle tandis que la boucle sera entrée au moins une fois.

+0

Vous obtenez 'NullPointerException' si' line' est null, mais vous avez raison de dire que la chaîne vide ne renverra aucun jeton. – Andreas

+0

ouais bien @Andreas. –