11
votes

Comment convertir une chaîne pour flotter et éviter d'utiliser Essayer / Catch à Java?

Il y a une situation que j'ai besoin de convertir une chaîne en flottant ou d'autres types de données numériques, mais il existe une probabilité d'obtenir des valeurs non convertibles telles que "-" ou "/" et je ne peux pas vérifier toutes les valeurs au préalable pour les supprimer. Et je veux éviter d'utiliser Essayer / Catch pour cette affaire, y a-t-il une autre façon de faire une conversion appropriée en Java? quelque chose de similaire à c # tryparse ?


14 commentaires

Pourquoi la contrainte artificielle sans exception? Afaik, tu devras rouler le vôtre!


Regardez Stackoverflow.com/a/1102916/1071777 La méthode isnumérique par CRAIGTP sera fondamentalement la trypairse (vous pouvez le modifier Selon vos besoins)


ce n'est pas moi de me traîner ses données basées sur des E / S provenant de quelque part donc je dois le rendre sain d'esprit


La question est la suivante: Si c'est Dodgy, vous voulez sûrement échouer rapidement et ne pas continuer?


@Nim, je ne l'appellerais pas du tout une contrainte artificielle, il suffit d'explorer de voir si la même fonctionnalité évitant une exception existe en Java comme dans la tryparse de .NET.


@AustinPowers Pourquoi pas simplement utiliser une regex pour vérifier la chaîne est ce que vous voulez si vous ne voulez pas exploiter le cadre et saisir l'exception? L'exception est explicitement définie pour indiquer que le format de numéro est incorrect. Votre combat le cadre ici.


@Anthonypegram, Hmm, me semble une perte de temps pour moi ... Attraper l'exception et manipulez-la - lié à être beaucoup plus rapidement que toute autre approche de hacky ...


@Nim, vous auriez tort de la revendication "beaucoup plus rapide", si vous gardez à l'esprit provenir d'une perspective C #. float.trypsarse est ordres de magnitude plus rapide lorsque vous traitez avec une entrée incorrecte. La manipulation des exceptions est lente et nous n'aimons pas non plus en s'appuyant sur des exceptions pour le flux de contrôle. Donc, comme Austin vient d'une perspective C #, il recherche cette même validation rapide et non exceptionnelle de l'entrée tout en fournissant simultanément à la sortie. Vous apprenez seulement que cela n'existe pas en Java en cherchant des conseils!


@Anthony vraiment? La manipulation des exceptions est lente? Bien dans un cas exceptionnel Oui, mais pour éviter, vous préférez frapper toutes les opérations avec les mêmes frais généraux?


@Nim, pourquoi penseriez-vous que Tryparse In .net vient avec beaucoup de frais généraux? Avez-vous exécuté des comparaisons de profilage pour le chemin heureux et des chemins exceptionnels entre les différentes techniques d'analyse des numéros afin de s'éloigner de cette conclusion, ou êtes-vous simplement en supposant?


Mais considérez le contexte, pas tous l'analyse de .net ne seraient fait avec Tryparse. Si, par exemple, les données provenaient d'un système connu pouvant être approuvé, un format invalide serait vraiment être exceptionnel et nous voudrions le traiter comme tel. Si, toutefois, nous avons affaire à une entrée de l'utilisateur, une entrée non valide est un événement beaucoup plus régulier et nous voudrions traiter cela en conséquence. Nous ne ferions pas cela en manipulant des exceptions, nous validerons et reppionnons simplement.


@Anthonypegram, je n'ai pas réclamé de telles choses, je n'ai aucune expérience C # C #, mais à partir des connaissances Little Java et C ++ que j'ai et que le code (que je considère comme étant de qualité exceptionnelle, que j'ai vu ), Je n'ai pas vu de cas où des exceptions sont évitées parce qu'elles sont "chères". Les exceptions sont abusées, mais utilisées correctement, elle est susceptible d'être moins chère que de diriger une expression régulière pour vérifier d'abord (?) De contextes d'oeil, mais laissez-moi vous mettre cela à vous, si vous validiez l'entrée de l'utilisateur, le «coût» d'un question d'exception?


@Nim, cela remonte à la deuxième partie. Si je valide la contribution de l'utilisateur, je ne vais pas laisser une exception piloter ma prise de décision. Cela fait des exceptions une partie du flux de contrôle, et c'est une mauvaise pratique de programmation dans .NET. Encore une fois, si vous êtes dans un environnement qui n'a pas cette approche, vous utilisez les outils que vous avez. En .NET, nous avons une tryparse, et il est rapide, fonctionnel et entièrement approprié pour son utilisation typique. Votre environnement peut différer, tout comme Java le fait évidemment.


Je pense que cela peut vous aider Cliquez ici .


4 Réponses :


5
votes

Malheureusement, il n'y a pas de méthode de ce type en Java. Il n'y a pas de paramètre de sortie en Java, alors écrire une telle méthode nécessiterait de renvoyer un flotteur null pour signaler une erreur ou pour passer un objet Floatholder qui pourrait être modifié par la méthode:

public class FloatHolder {
    private float value;

    public void setValue(float value) {
        this.value = value;
    }

    public float getValue() {
        return this.value;
    }
}

public static boolean tryParseFloat(String s, FloatHolder holder) {
    try {
        float value = Float.parseFloat(s);
        holder.setValue(value);
    }
    catch (NumberFormatException e) {
        return false;
    }
}


4 commentaires

Mon point est: Évitez d'utiliser Essayer / Catch pour analyser de telles valeurs simples, mais merci pour l'approche


Sauf en réinitialisant la parsefloat vous-même, vous ne pourrez pas le faire. Si tout votre code utilise la méthode Tryparsfloat, il n'est pas nécessaire de faire face aux exceptions. Seul tryparsefloat fait.


Pouvez-vous ne pas utiliser de float ? (Mon Java est un peu rouillé) - ce qu'il y a avec le floatholder ?


Vous pouvez utiliser un flotteur et renvoyer NULL pour signaler une erreur. Je l'ai suggéré dans ma réponse. Le Floatholder est un moyen d'avoir une signature similaire à la méthode Tryparse C #.



1
votes

Java ne fournit pas d'autres méthodes de trypairse intégrées, sur les solutions que vous pouvez essayer consiste à créer votre propre méthode Tryparse et à mettre un code TRY / Catch dans cette méthode, puis vous pouvez facilement utiliser cette méthode sur votre application. Facilement et sans utiliser Essayer / Catch à tous les endroits que vous utilisez la méthode.

L'une des fonctions d'échantillon peut avoir le code suivant P>

public static Long parseLong(String value) {

        if(isNullOrEmpty(value)) {
            return null;
        }

        try {
            return Long.valueOf(value);
        }
        catch (NumberFormatException e) {
        }

        return null;
    }


0 commentaires

6
votes

La chose la plus simple que je puisse penser est java.util.scanner code>. Toutefois, cette approche nécessite une nouvelle instance de scanner pour chaque chaîne.

Pattern p = Pattern.compile("insert regex to test string here");
String data = ...;
Matcher m = p.matcher(data);
//warning depending on regex used this may 
//only check part of the string
if(m.matches()){
  int i = Integer.parseInt(data);
}


6 commentaires

et la regex est "((- | \\ +)? [0-9] + (\\. [0-9] +)?) +"


Je suis désolé, mais je dirais que l'approche de contrôle d'expression régulière sera plus lente que de simplement attraper une exception d'analyse, semble être une optimisation prématurée pour moi.


@Nim c'est pourquoi j'ai écrit la dernière phrase et la plus probablement la raison pour laquelle Java n'a pas d'analyse d'essai, sa plus lente lorsque la plupart des valeurs sont valides.


Au cas où n'importe qui à l'avenir veut une bonne solution pour les doubles, voici la regex pour cela: ^ [- +]? [0-9] * \. [0-9] + $ et il Ne laissez rien d'autre dans la chaîne d'être quelque chose que des chiffres (donc ne vous inquiétez pas du commentaire d'avertissement dans le code ci-dessus)


Pas sûr si Apache utilise simplement une capture de try, mais pour que quiconque achète ici qui veut juste une méthode utilitaire, il existe Numberutils.toint (Str, DefaultValue): Commons.apache.org /proper/commons-lang/javadocs/api-3.3.2/or g / ...


J'ai confirmé, Apach utilise Essayer Catch.



1
votes

C'est une question ancienne, mais puisque toutes les réponses ne parlaient pas de cela (et je ne l'ai pas consciée moi-même jusqu'à ce que je le vois dans une demande de fusion écrite par une collègue), je veux poser des lecteurs potentiels à la < Un href = "https://github.com/google/guava" rel = "nofollow NOREFERRER"> GUAVA flotte et intens classes:

Avec l'aide de ces classes, vous pouvez écrire du code comme celui-ci: xxx

Le résultat sera null si la valeur est un invalide int ou float , et vous pouvez ensuite le gérer de quelque manière que ce soit. (Soyez prudent de ne pas simplement le jeter à un int / float , car cela déclenchera un nullpointexception si la valeur est un entier / flottant non valide valeur ponctuelle.)

Notez que ces méthodes sont marquées comme "bêta", mais elles sont très utiles quand même et nous les utilisons en production.

Pour référence, voici les Javadocs pour Ces classes:


0 commentaires