J'utilise normalement l'idiome suivant pour vérifier si une chaîne peut être convertie en entier.
public boolean isInteger( String input ) {
try {
Integer.parseInt( input );
return true;
}
catch( Exception e ) {
return false;
}
}
Est-ce juste moi ou cela semble-t-il un peu hack? Quelle meilleure façon?
Voir ma réponse (avec des repères, basée sur la réponse précédente de CodingWithSpike ) pour voir pourquoi j'ai inversé ma position et accepté la réponse de Jonas Klemming à ce problème. Je pense que ce code original sera utilisé par la plupart des gens car il est plus rapide à implémenter et plus facile à maintenir, mais ses ordres de grandeur sont plus lents lorsque des données non entières sont fournies.
Réponses:
Si vous n'êtes pas préoccupé par des problèmes de débordement potentiels, cette fonction fonctionnera environ 20 à 30 fois plus rapidement que l'utilisation
Integer.parseInt()
.la source
Vous l'avez, mais vous ne devriez attraper
NumberFormatException
.la source
A fait une référence rapide. Les exceptions ne sont pas vraiment aussi coûteuses, à moins que vous ne commenciez à réapparaître plusieurs méthodes et que la JVM doive faire beaucoup de travail pour mettre la pile d'exécution en place. En restant dans la même méthode, ils ne sont pas mauvais interprètes.
Production:
Je suis d'accord que la solution de Jonas K est également la plus robuste. On dirait qu'il gagne :)
la source
^
et$
deuxième fois puisque dans lamatches
chaîne entière doit correspondre regex, (2) àstr.matches
chaque fois que devra créer sa proprePattern
qui est cher. Pour des raisons de performances, nous ne devons créer ce modèle qu'une seule fois en dehors de cette méthode et l'utiliser à l'intérieur. (3) Nous pouvons également créer un seul objet Matcher et l'utiliserreset(CharSequence)
pour transmettre des données utilisateur et renvoyer sonmatches()
résultat.private final Matcher m = Pattern.compile("-?\\d+").matcher(""); private boolean byRegex(String str) { return m.reset(str).matches(); }
devrait avoir de meilleures performances.matches
ajoute^
et$
implicitement. Jetez un oeil au résultat de" 123".matches("\\d+")
et"123".matches("\\d+")
. Vous verrezfalse
ettrue
.false
sera renvoyée car la chaîne commence par un espace qui l'empêche d'être entièrement mise en correspondance par l'expression régulière.Puisqu'il est possible que les gens visitent toujours ici et soient biaisés contre Regex après les benchmarks ... Je vais donc donner une version mise à jour du benchmark, avec une version compilée du Regex. Contrairement aux benchmarks précédents, celui-ci montre que la solution Regex a en fait toujours de bonnes performances.
Copié de Bill the Lizard et mis à jour avec la version compilée:
Résultats:
la source
336
."^[+-]?\\d+$"
serait peut -être encore mieux.bien que la bibliothèque standard de Java manque vraiment de telles fonctions utilitaires
Je pense qu'Apache Commons est un "must have" pour tout programmeur Java
dommage qu'il ne soit pas encore porté sur Java5
la source
Cela dépend en partie de ce que vous entendez par «peut être converti en entier».
Si vous voulez dire "peut être converti en un entier en Java", la réponse de Jonas est un bon début, mais ne termine pas tout à fait le travail. Il passerait par exemple 999999999999999999999999999999. J'ajouterais l'appel try / catch normal à partir de votre propre question à la fin de la méthode.
Les vérifications caractère par caractère rejetteront efficacement les cas "pas un entier du tout", laissant "c'est un entier mais Java ne peut pas le gérer" les cas pour être capturés par la route d'exception la plus lente. Tu pouvez aussi le faire à la main, mais ce serait beaucoup plus compliqué.
la source
Juste un commentaire sur regexp. Chaque exemple fourni ici est faux !. Si vous souhaitez utiliser regexp, n'oubliez pas que la compilation du modèle prend beaucoup de temps. Ce:
et aussi ceci:
provoque la compilation du modèle dans chaque appel de méthode. Pour l'utiliser correctement, suivez:
la source
Il existe une version goyave:
Il renverra null au lieu de lever une exception s'il ne parvient pas à analyser la chaîne.
la source
J'ai copié le code de la réponse rally25rs et ajouté quelques tests pour les données non entières. Les résultats sont indéniablement en faveur de la méthode publiée par Jonas Klemming. Les résultats de la méthode Exception que j'ai publiée à l'origine sont assez bons lorsque vous avez des données entières, mais ils sont les pires lorsque vous n'en avez pas, tandis que les résultats de la solution RegEx (que je parie que beaucoup de gens utilisent) étaient toujours mauvais. Voir la réponse de Felipe pour un exemple regex compilé, qui est beaucoup plus rapide.
Résultats:
la source
C'est plus court, mais plus court n'est pas nécessairement meilleur (et il n'attrapera pas les valeurs entières qui sont hors de portée, comme souligné dans le commentaire de danatel ):
Personnellement, étant donné que l'implémentation est éculée dans une méthode d'assistance et que l'exactitude l'emporte sur la longueur, j'irais simplement avec quelque chose comme ce que vous avez (moins attraper la
Exception
classe de base plutôt queNumberFormatException
).la source
Vous pouvez utiliser la méthode matches de la classe de chaîne. Le [0-9] représente toutes les valeurs qu'il peut être, le + signifie qu'il doit comporter au moins un caractère et le * signifie qu'il peut comporter zéro ou plusieurs caractères.
la source
Que diriez-vous:
la source
Il s'agit d'une variante Java 8 de la réponse de Jonas Klemming:
Code de test:
Résultats du code de test:
la source
Vous venez de vérifier NumberFormatException : -
la source
Si votre tableau de chaînes contient des entiers et des chaînes purs, le code ci-dessous devrait fonctionner. Il suffit de regarder le premier caractère. par exemple ["4", "44", "abc", "77", "bond"]
la source
Vous pouvez également utiliser la classe Scanner et utiliser hasNextInt () - et cela vous permet également de tester d'autres types, comme les flottants, etc.
la source
Si vous voulez vérifier si la chaîne représente un entier qui tient dans un type int, j'ai fait une petite modification à la réponse des jonas, de sorte que les chaînes qui représentent des entiers plus grands que Integer.MAX_VALUE ou plus petits que Integer.MIN_VALUE, vont maintenant retourner faux. Par exemple: "3147483647" renverra false car 3147483647 est plus grand que 2147483647, et de même, "-2147483649" renverra également false car -2147483649 est plus petit que -2147483648.
la source
trim()
donc c'est clairement un choix de conception intentionnel.Vous pouvez essayer des utils apache
Voir le javadoc ici
la source
isCreateable(String)
place.Vous devez probablement également tenir compte du cas d'utilisation:
Si, la plupart du temps, vous vous attendez à ce que les nombres soient valides, la capture de l'exception ne provoque qu'une surcharge de performances lorsque vous tentez de convertir des nombres non valides. Alors que l'appel d'une
isInteger()
méthode, puis la conversion à l'aideInteger.parseInt()
entraînera toujours une surcharge de performances pour les nombres valides - les chaînes sont analysées deux fois, une fois par la vérification et une fois par la conversion.la source
Il s'agit d'une modification du code de Jonas qui vérifie si la chaîne se trouve dans la plage à convertir en entier.
la source
Si vous utilisez l'API Android, vous pouvez utiliser:
la source
Une autre option:
la source
la source
Ce que vous avez fait fonctionne, mais vous ne devriez probablement pas toujours vérifier de cette façon. Le lancement d'exceptions doit être réservé aux situations "exceptionnelles" (peut-être que cela vous convient, cependant), et sont très coûteux en termes de performances.
la source
la source
Cela ne fonctionnerait que pour les entiers positifs.
la source
Cela fonctionne pour moi. Identifier simplement si une chaîne est une primitive ou un nombre.
la source
Pour vérifier tous les caractères int, vous pouvez simplement utiliser un double négatif.
if (! searchString.matches ("[^ 0-9] + $")) ...
[^ 0-9] + $ vérifie s'il y a des caractères qui ne sont pas des nombres entiers, donc le test échoue si c'est vrai. Ce n'est PAS le cas et vous réussissez.
la source
matches
méthode correspond à la chaîne entière, pas seulement à une partie de celle-ci.if
bloc. Ça ne devrait pas.Trouvez ceci peut être utile:
la source
Je crois qu'il ya risque zéro en cours d' exécution dans une exception, parce que vous pouvez voir ci - dessous vous analysez toujours en toute sécurité
int
àString
et non l'inverse.Alors:
Vous vérifiez si chaque emplacement de caractère de votre chaîne correspond à au moins un des caractères {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"} .
Vous additionnez toutes les fois que vous avez rencontré dans les emplacements les personnages ci-dessus.
Et enfin, vous vérifiez si le nombre de fois où vous avez rencontré des entiers sous forme de caractères est égal à la longueur de la chaîne donnée.
Et dans la pratique, nous avons:
Et les résultats sont:
De même, vous pouvez valider si a
String
est unfloat
ou un,double
mais dans ces cas, vous ne devez en rencontrer qu'un. (point) dans la chaîne et bien sûr vérifier sidigits == (aString.length()-1)
J'espère avoir aidé
la source