J'ai un projet dans lequel nous utilisons souvent Integer.parseInt()
pour convertir une chaîne en un int. Lorsque quelque chose ne va pas (par exemple, le String
n'est pas un nombre mais une lettre a
, ou autre), cette méthode lèvera une exception. Cependant, si je dois gérer des exceptions dans mon code partout, cela commence à paraître très moche très rapidement. Je voudrais mettre cela dans une méthode, cependant, je ne sais pas comment renvoyer une valeur propre afin de montrer que la conversion s'est mal passée.
En C ++, j'aurais pu créer une méthode qui accepte un pointeur vers un int et laisse la méthode elle-même retourner true ou false. Cependant, pour autant que je sache, ce n'est pas possible en Java. Je pourrais également créer un objet contenant une variable vrai / faux et la valeur convertie, mais cela ne semble pas non plus idéal. La même chose vaut pour une valeur globale, et cela pourrait me poser quelques problèmes avec le multithreading.
Alors, y a-t-il un moyen propre de faire cela?
la source
int
alors que 2147483648 ne l'est pas.Réponses:
Vous pouvez retourner un
Integer
au lieu d'unint
, en retournantnull
en cas d'échec de l'analyse.C'est dommage que Java ne fournisse pas un moyen de le faire sans qu'une exception soit lancée en interne - vous pouvez masquer l'exception (en l'attrapant et en renvoyant null), mais cela pourrait toujours être un problème de performances si vous analysez des centaines de milliers de bits de données fournies par l'utilisateur.
EDIT: Code pour une telle méthode:
Notez que je ne suis pas sûr du haut de ma tête ce que cela fera si
text
est nul. Vous devriez considérer que - si cela représente un bogue (c'est-à-dire que votre code peut bien passer une valeur invalide, mais ne devrait jamais passer null), alors lancer une exception est approprié; si cela ne représente pas un bogue, vous devriez probablement simplement renvoyer null comme vous le feriez pour toute autre valeur invalide.À l'origine, cette réponse utilisait le
new Integer(String)
constructeur; il utilise maintenantInteger.parseInt
et une opération de boxe; de cette façon, les petites valeurs finiront par être encadrées dans desInteger
objets mis en cache , ce qui le rendra plus efficace dans ces situations.la source
null
références que de gérer régulièrement les exceptions.À quel comportement attendez-vous quand ce n'est pas un nombre?
Si, par exemple, vous avez souvent une valeur par défaut à utiliser lorsque l'entrée n'est pas un nombre, une méthode comme celle-ci peut être utile:
Des méthodes similaires peuvent être écrites pour un comportement par défaut différent lorsque l'entrée ne peut pas être analysée.
la source
Dans certains cas, vous devez gérer les erreurs d'analyse comme des situations de défaillance rapide, mais dans d'autres cas, tels que la configuration de l'application, je préfère gérer les entrées manquantes avec des valeurs par défaut à l'aide d' Apache Commons Lang 3 NumberUtils .
la source
Pour éviter de gérer les exceptions, utilisez une expression régulière pour vous assurer que vous avez tous les chiffres en premier:
la source
Il y
Ints.tryParse()
en a à Goyave . Il ne lève pas d'exception sur une chaîne non numérique, mais il renvoie une exception sur une chaîne nulle.la source
Après avoir lu les réponses à la question, je pense qu'encapsuler ou encapsuler la méthode parseInt n'est pas nécessaire, peut-être même pas une bonne idée.
Vous pouvez retourner 'null' comme Jon l'a suggéré, mais cela remplace plus ou moins une construction try / catch par une vérification null. Il y a juste une légère différence sur le comportement si vous «oubliez» la gestion des erreurs: si vous n'attrapez pas l'exception, il n'y a pas d'affectation et la variable de gauche conserve l'ancienne valeur. Si vous ne testez pas null, vous serez probablement touché par la JVM (NPE).
La suggestion de bâillement me paraît plus élégante, car je n'aime pas renvoyer null pour signaler des erreurs ou des états exceptionnels. Vous devez maintenant vérifier l'égalité référentielle avec un objet prédéfini, cela indique un problème. Mais, comme d'autres le soutiennent, si à nouveau vous «oubliez» de vérifier et qu'une chaîne est impossible à analyser, le programme continue avec l'int enveloppé dans votre objet «ERROR» ou «NULL».
La solution de Nikolay est encore plus orientée objet et fonctionnera également avec les méthodes parseXXX d'autres classes wrapper. Mais à la fin, il vient de remplacer le NumberFormatException par une exception OperationNotSupported - encore une fois, vous avez besoin d'un try / catch pour gérer les entrées non analysables.
Donc, c'est ma conclusion de ne pas encapsuler la méthode simple parseInt. Je n'encapsulerais que si je pouvais également ajouter une gestion des erreurs (en fonction de l'application).
la source
Vous pouvez peut-être utiliser quelque chose comme ceci:
la source
Vous pouvez également répliquer très simplement le comportement C ++ que vous souhaitez
Vous utiliseriez la méthode comme ceci:
Après cela, la variable
result
est vraie si tout s'est bien passé etbyRef[0]
contient la valeur analysée.Personnellement, je m'en tiendrai à attraper l'exception.
la source
La réponse donnée par Jon Skeet est bonne, mais je n'aime pas rendre un
null
objet Integer. Je trouve cela déroutant à utiliser. Depuis Java 8, il existe une meilleure option (à mon avis), en utilisant leOptionalInt
:Cela rend explicite le fait que vous devez gérer le cas où aucune valeur n'est disponible. Je préférerais que ce type de fonction soit ajouté à la bibliothèque java à l'avenir, mais je ne sais pas si cela arrivera un jour.
la source
Si vous utilisez Java 8 ou une version ultérieure, vous pouvez utiliser une bibliothèque que je viens de publier: https://github.com/robtimus/try-parse . Il prend en charge int, long et boolean qui ne repose pas sur la capture d'exceptions. Contrairement à Ints.tryParse de Guava, il renvoie OptionalInt / OptionalLong / Optional, un peu comme dans https://stackoverflow.com/a/38451745/1180351 mais plus efficace.
la source
Mon Java est un peu rouillé, mais laissez-moi voir si je peux vous orienter dans la bonne direction:
Si votre valeur de retour est
null
, vous avez une mauvaise valeur. Sinon, vous disposez d'un fichierInteger
.la source
Integer.tryParse
dans laInteger
classe Java standard . 2. Fairenew Integer
est inutile (et déconseillé) car Java fait automatiquement la boxe et le déballage. Votre Java n'est pas seulement un peu rouillé, il est très rouillé.Qu'en est-il de la méthode parseInt ?
C'est facile, il suffit de copier-coller le contenu dans un nouvel utilitaire qui renvoie
Integer
ouOptional<Integer>
et de remplacer les lancers par des retours. Il semble qu'il n'y ait pas d'exceptions dans le code sous-jacent, mais mieux vérifier .En ignorant toute la gestion des exceptions, vous pouvez gagner du temps sur les entrées non valides. Et la méthode existe depuis JDK 1.0, il est donc peu probable que vous ayez à faire grand-chose pour la maintenir à jour.
la source
Je vous suggère d'envisager une méthode comme
que vous implémentez ensuite comme bon vous semble. Si vous voulez que le résultat soit reporté - peut-être parce que vous utilisez de toute façon Integer.parseInt () - vous pouvez utiliser l'astuce du tableau.
où vous définissez result [0] sur la valeur entière trouvée dans le processus.
la source
Ceci est un peu similaire à la solution de Nikolay:
La méthode principale démontre le code. Une autre façon d'implémenter l'interface Parser serait évidemment de simplement définir "\ D +" à partir de la construction, et de laisser les méthodes ne rien faire.
la source
Vous pouvez lancer la vôtre, mais c'est tout aussi simple d'utiliser la
StringUtils.isNumeric()
méthode de commons lang . Il utilise Character.isDigit () pour parcourir chaque caractère de la chaîne.la source
La manière dont je gère ce problème est récursive. Par exemple lors de la lecture de données depuis la console:
la source
Pour éviter une exception, vous pouvez utiliser la
Format.parseObject
méthode Java . Le code ci-dessous est essentiellement une version simplifiée de la classe IntegerValidator d'Apache Common .Vous pouvez utiliser
AtomicInteger
ouint[]
astuce tableau en fonction de vos préférences.Voici mon test qui l'utilise -
la source
J'avais aussi le même problème. C'est une méthode que j'ai écrite pour demander à l'utilisateur une entrée et n'accepter l'entrée que si elle est un entier. Veuillez noter que je suis un débutant donc si le code ne fonctionne pas comme prévu, blâmez mon inexpérience!
la source
Ceci est une réponse à la question 8391979, "Est-ce que java a un int.tryparse qui ne lève pas d'exception pour les mauvaises données? [Dupliquer]" qui est fermé et lié à cette question.
Edit 2016 08 17: Ajout des méthodes ltrimZeroes et les a appelées dans tryParse (). Sans zéros non significatifs dans numberString peut donner de faux résultats (voir les commentaires dans le code). Il existe maintenant aussi la méthode publique statique String ltrimZeroes (String numberString) qui fonctionne pour les «nombres» positifs et négatifs (END Edit)
Vous trouverez ci-dessous une classe rudimentaire Wrapper (boxing) pour int avec une méthode tryParse () hautement optimisée pour la vitesse (similaire à C #) qui analyse la chaîne elle-même et est un peu plus rapide que Integer.parseInt (String s) de Java:
Programme de test / exemple pour la classe IntBoxSimple:
la source
Essayez avec une expression régulière et un argument de paramètres par défaut
si vous utilisez apache.commons.lang3, utilisez NumberUtils :
la source
Je voudrais ajouter une autre proposition qui fonctionne si l'on demande spécifiquement des entiers: utilisez simplement long et utilisez Long.MIN_VALUE pour les cas d'erreur. Ceci est similaire à l'approche qui est utilisée pour les caractères dans Reader où Reader.read () renvoie un entier dans la plage d'un caractère ou -1 si le lecteur est vide.
Pour Float et Double, NaN peut être utilisé de la même manière.
la source
Compte tenu des réponses existantes, j'ai copié-collé et amélioré le code source de
Integer.parseInt
pour faire le travail, et ma solutionInts.tryParse()
),int[]
,Box
,OptionalInt
),CharSequence
ou partie au lieu d'un toutString
,Integer.parseInt
peut, ie [2,36],Le seul inconvénient est qu'il n'y a pas de différence entre
toIntOfDefault("-1", -1)
ettoIntOrDefault("oops", -1)
.la source
Vous pouvez utiliser un Null-Object comme ceci:
Le résultat de main dans cet exemple est:
De cette façon, vous pouvez toujours tester la conversion échouée, mais toujours travailler avec les résultats en tant qu'instances Integer. Vous pouvez également modifier le nombre représenté par NULL (≠ 0).
la source
Vous ne devez pas utiliser d'exceptions pour valider vos valeurs .
Pour un caractère unique, il existe une solution simple:
Pour des valeurs plus longues, il est préférable d'utiliser certains utilitaires. NumberUtils fourni par Apache fonctionnerait parfaitement ici:
Veuillez vérifier https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/math/NumberUtils.html
la source
Integer.parseInt
.