Quelle est la meilleure façon de vérifier si une Chaîne de caractères représente un nombre entier en Java?
J'ai l'habitude de suivre la marche suivante pour vérifier si une Chaîne de caractères peut être converti en entier.
public boolean isInteger( String input ) {
try {
Integer.parseInt( input );
return true;
}
catch( Exception e ) {
return false;
}
}
Est-ce juste moi, ou cela vous semble un peu hackish? Ce qui est une meilleure façon?
Voir ma réponse (avec des repères, basé sur la auparavant répondre par CodingWithSpike) pour voir pourquoi j'ai inversé ma position et accepté Jonas Klemming réponse à ce problème. Je pense que ce code original sera utilisé par la plupart des gens, car il est plus rapide à mettre en œuvre, et plus facile à gérer, mais c'est des ordres de grandeur plus lente lorsque la non-entier de données est fourni.
- Ce que votre idée sur les RegExp pour la solution?
Vous devez vous connecter pour publier un commentaire.
Si vous n'êtes pas concerné avec d'éventuels problèmes de dépassement de cette fonction permettra de réaliser de 20 à 30 fois plus rapide que l'utilisation
Integer.parseInt()
.\d
, ce qui évite les dépendances à la fois sur le chiffre caractères (par exemple '0' et '9' vs persan les chiffres) et sur la commande de celle-ci (la<
>
comparaison). Ces dépendances sont en fait fragile, comme vous le verrez une fois que votre entiers arrivent à la recherche comme۵۷۱۰
. La regex pourrait réellement fonctionner out-of-the-box, en supposant que les paramètres régionaux sont définis correctement.Vous l'avez, mais vous ne devez attraper
NumberFormatException
.java.lang.Exception
(ouThrowable
), en démontrant comment il est trop facile de manquer un.Fait un rapide test. Les Exceptions ne sont pas réellement que expensivve, sauf si vous commencez à éclater de multiples méthodes et la JVM doit faire beaucoup de travail pour obtenir l'exécution de la pile en place. Lors de votre séjour dans la même méthode, ils ne sont pas mauvais artistes.
De sortie:
Je suis d'accord que Jonas K est la solution la plus robuste aussi. On dirait qu'il gagne 🙂
^
et$
deuxième fois depuis dansmatches
ensemble de la chaîne doit correspondre regex, (2)str.matches
chaque fois, devra créer son proprePattern
qui est cher. Pour des raisons de performances, nous devrions créer un tel Motif qu'une seule fois en dehors de cette méthode et de l'utiliser à l'intérieur. (3) Nous pouvons également créer une seule Matcher objet et l'utilisation de sonreset(CharSequence)
pour transmettre les données de l'utilisateur et de sesmatches()
résultat.private final Matcher m = Pattern.compile("-?\\d+").matcher(""); private boolean byRegex(String str) { return m.reset(str).matches(); }
devrait avoir une meilleure performance.matches
est l'ajout de^
et$
implicitement. Jetez un oeil à la suite de" 123".matches("\\d+")
et"123".matches("\\d+")
. Vous verrezfalse
ettrue
.false
sera retourné parce que la chaîne commence avec l'espace qui l'empêche d'être entièrement compensée par la regex.Puisqu'il y a possibilité que les gens continuent de visiter ici et seront biaisés contre les Regex après les benchmarks... Donc je vais donner une version mise à jour de l'indice de référence, avec une version compilée de la Regex. Qui s'est opposée à la précédente repères, cette montre Regex solution en fait a toujours de bonnes performances.
Copié à partir de Bill le Lézard et mis à jour avec la version compilée:
Résultats:
336
."^[+-]?\\d+$"
serait encore mieux.si Java standard lib manque réellement de telles fonctions de l'utilitaire de
Je pense que Apache Commons est un "must have" pour tous les programmeurs Java
trop mauvais, il n'est pas porté à Java5 encore
Il dépend en partie de ce que vous entendez par "peut être converti en entier".
Si vous voulez dire "peut être converti en int en Java", alors la réponse de Jonas est un bon début, mais n'a pas tout à fait terminer le travail. Il passerait 999999999999999999999999999999 par exemple. Je voudrais ajouter à la normale try/catch appel à partir de votre propre question à la fin de la méthode.
Le caractère par caractère vérifie de façon efficace les rejeter "pas un nombre entier, à tous les" en cas, quitter "c'est un entier, mais Java ne peut pas le manipuler" les cas d'être pris par le ralentissement de l'exception de l'itinéraire. Vous pourrait faire ce peu à la main aussi, mais ce serait une beaucoup plus compliqué.
Juste un commentaire à propos de regexp. Chaque exemple donné ici est faux!. Si vous souhaitez utiliser regexp n'oubliez pas que la compilation du motif de prendre beaucoup de temps. Ce:
et également ceci:
causes de la compilation de modèle dans chaque appel de méthode. Utilisé correctement suivre:
J'ai copié le code de rally25rs réponse, et a ajouté quelques tests pour les données non entier. Les résultats sont indéniablement en faveur de la méthode posté par Jonas Klemming. Les résultats de l'Exception de la méthode que j'ai posté sont assez bien quand vous avez des données entier, mais ils sont les pires quand vous ne le faites pas, alors que les résultats pour l'expression rationnelle de la solution (que je parie que beaucoup de gens utilisent) ont été constamment mauvais. Voir Felipe répondre pour la compilation d'un regex exemple, qui est beaucoup plus rapide.
Résultats:
Il y a goyave version:
Il va retourner la valeur null au lieu de lancer une exception si elle ne parvient pas à analyser la chaîne.
C'est plus courte, mais plus court n'est pas forcément mieux (et il ne sera pas attraper des valeurs entières qui sont hors de portée, comme l'a souligné dans danatel commentaire):
Personnellement, depuis la mise en œuvre est squirrelled loin dans une méthode d'aide et de l'exactitude des atouts de la longueur, je voudrais juste aller avec quelque chose comme ce que vous avez (moins la capture de la base de
Exception
classe plutôt que deNumberFormatException
).Vous pouvez utiliser les matches de la méthode de la classe string. L' [0-9] représente l'ensemble des valeurs qu'elle peut être, le + signifie qu'il doit être au moins un caractère de long, et le * signifie qu'il peut y avoir zéro ou plusieurs caractères.
Comment sur:
C'est une Java 8 variation de Jonas Klemming réponse:
Code de Test:
Résultats du test de code:
Vous suffit de cocher NumberFormatException:-
Si votre tableau de Chaîne contient des Entiers et des Chaînes de code ci-dessous devrait fonctionner. Vous n'avez qu'à regarder au premier caractère.
par exemple ["4","44","abc","77","lien"]
Vous pouvez également utiliser le Scanner de classe, et l'utilisation hasNextInt() - et cela vous permet de tester d'autres types, comme des flotteurs, etc.
Vous pouvez essayer de apache utils
Voir la javadoc ici
Vous avez probablement besoin de prendre le cas d'utilisation en compte:
Si la plupart du temps vous vous attendez à des nombres pour être valide, la capture de l'exception n'est qu'en provoquant une surcharge de performance lors de la tentative de convertir les numéros non valides. Alors que l'appel de certains
isInteger()
méthode et ensuite de les convertir à l'aide deInteger.parseInt()
sera toujours cause d'une surcharge de performance pour la validité des numéros - les cordes sont analysés deux fois, une fois par la case et une fois par la conversion.C'est une modification de Jonas code qui vérifie si la chaîne est dans la plage pour être jeté dans un entier.
Si vous utilisez l'API Android, vous pouvez utiliser:
Une autre option:
Si vous voulez vérifier si la chaîne de caractères représente un entier qui correspond à un type int, j'ai fait une petite modification à l'jonas répondre, de sorte que les chaînes de caractères qui représentent des nombres entiers plus grands que Entier.MAX_VALUE ou plus petit que Entier.MIN_VALUE, sera de retour faux. Par exemple: "3147483647" sera de retour faux car 3147483647 est plus grand que 2147483647, et de même, "-2147483649" sera également de retour faux car -2147483649 est plus petit que -2147483648.
Ce que vous avez fait des œuvres, mais vous ne devriez probablement pas de toujours vérifier de cette façon. De lever des exceptions doit être réservée aux situations "exceptionnelles" (peut-être qui s'adapte à votre cas, tout de même), et sont très coûteuses en termes de performances.
Cela ne peut fonctionner que pour des entiers positifs.
Cela fonctionne pour moi. Simplement pour déterminer si une Chaîne est une primitive ou un nombre.
Pour vérifier tous les int caractères, vous pouvez simplement utiliser un double négatif.
if (!searchString.matchs("[^0-9]+$")) ...
[^0-9]+$ vérifie s'il y a des caractères qui ne sont pas entiers, de sorte que le test échoue si c'est vrai. PAS juste que, et vous obtenez true en cas de succès.
matches
méthode correspond à l'encontre de l'ensemble de la chaîne, et pas seulement une partie.if
bloc. Il ne devrait pas.Trouver cela peut aider:
Je crois qu'il y a zéro risque en cours d'exécution dans une exception, parce que comme vous pouvez le voir ci-dessous vous toujours en toute sécurité analyser
int
àString
et non l'inverse.Donc:
Vous vérifier si chaque slot de personnage dans votre chaîne de caractères correspond au moins à
l'un des personnages {"0","1","2","3","4","5","6","7","8","9"}.
Vous somme toutes les fois que vous avez rencontré dans les emplacements ci-dessus
des personnages.
Et enfin, vous vérifier si le temps que vous avez rencontré des nombres entiers comme
caractères est égale à la longueur de la chaîne.
Et, dans la pratique, nous avons:
Et les résultats sont les suivants:
De la même façon, vous pouvez vérifier si un
String
est unfloat
ou undouble
mais dans ces cas, vous avez à rencontrer seul . (dot) dans la Chaîne et, bien sûr vérifier sidigits == (aString.length()-1)
J'espère que j'ai aidé
J'ai vu beaucoup de réponses ici, mais la plupart d'entre eux sont en mesure de déterminer si la Chaîne est numérique, mais ils ne parviennent pas à vérifier si le numéro est dans l'intervalle Entier...
Donc j'ai voulu quelque chose comme ceci:
Lorsque les explications sont plus importants que les performances
J'ai remarqué beaucoup de discussions centrage de l'efficacité de certaines solutions, mais aucune sur les pourquoi une chaîne n'est pas un entier. Aussi, tout le monde semble supposer que le nombre "2.00" n'est pas égal à "2". Mathématiquement et humainement parlant, ils sont égalité (même si l'ordinateur la science dit qu'ils ne le sont pas, et pour une bonne raison). C'est pourquoi le "nombre Entier.parseInt" solutions ci-dessus sont faibles (selon vos besoins).
En tout cas, à rendre les logiciels plus intelligents et les plus bénéfiques pour l'être humain, nous avons besoin de créer des logiciels qui pense comme nous et explique pourquoi quelque chose a échoué. Dans ce cas:
Code de Test:
Je n'aime pas la méthode avec la regex, parce que la regex ne peut pas vérifier les plages (
Integer.MIN_VALUE
,Integer.MAX_VALUE
).Si vous vous attendez int valeur dans la plupart des cas, et pas int est quelque chose de rare, alors je suggère version avec
Integer.valueOf
ouInteger.parseInt
avecNumberFormatException
attraper. L'avantage de cette approche - votre code a bien des raisons de lisibilité:Si vous avez besoin de vérifier si la Chaîne est de type entier, et se soucient de perfomance alors le meilleur moyen est d'utiliser le jdk java mise en œuvre de
Integer.parseInt
, mais peu modifiée (en remplacement de lancer avec return false):Cette fonction a une bonne perfomence et de la garantie de bon résultat:
Pour les lecteurs qui arrivent ici, comme moi, des années après que la question a été posée, j'ai plus de solution générale de cette question.
fonctionne pour moi la plupart du temps!