249 votes

Ce qui ' s la meilleure façon de vérifier si une chaîne représente un entier en Java ?

J'ai l'habitude de suivre la marche suivante pour vérifier si une Chaîne de caractères peut être convertie en un nombre 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ée sur la précédente réponse par CodingWithSpike) pour voir pourquoi j'ai inversé ma position et accepté Jonas Klemming la 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.

193voto

Jonas Klemming Points 1377

Si vous n’êtes pas concernés par les problèmes potentiels de débordement que cette fonction se produira environ 20 à 30 fois plus rapidement qu’avec un Integer.parseInt().

68voto

Ovidiu Pacurar Points 5129

Vous l’avez, mais vous devriez prendre seulement `` .

44voto

CodingWithSpike Points 17720

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 interprètes ou exécutants.

public void RunTests()
{
    String str = "1234567890";

    long startTime = System.currentTimeMillis();
    for(int i = 0; i < 100000; i++)
        IsInt_ByException(str);
    long endTime = System.currentTimeMillis();
    System.out.print("ByException: ");
    System.out.println(endTime - startTime);

    startTime = System.currentTimeMillis();
    for(int i = 0; i < 100000; i++)
        IsInt_ByRegex(str);
    endTime = System.currentTimeMillis();
    System.out.print("ByRegex: ");
    System.out.println(endTime - startTime);

    startTime = System.currentTimeMillis();
    for(int i = 0; i < 100000; i++)
        IsInt_ByJonas(str);
    endTime = System.currentTimeMillis();
    System.out.print("ByJonas: ");
    System.out.println(endTime - startTime);
}

private boolean IsInt_ByException(String str)
{
    try
    {
        Integer.parseInt(str);
        return true;
    }
    catch(NumberFormatException nfe)
    {
        return false;
    }
}

private boolean IsInt_ByRegex(String str)
{
    return str.matches("^-?\\d+$");
}

public boolean IsInt_ByJonas(String str)
{
    if (str == null) {
            return false;
    }
    int length = str.length();
    if (length == 0) {
            return false;
    }
    int i = 0;
    if (str.charAt(0) == '-') {
            if (length == 1) {
                    return false;
            }
            i = 1;
    }
    for (; i < length; i++) {
            char c = str.charAt(i);
            if (c <= '/' || c >= ':') {
                    return false;
            }
    }
    return true;
}

Sortie:

ByException: 31

ByRegex: 453

ByJonas: 16

Je suis d'accord que Jonas K de la solution est la plus robuste. On dirait qu'il gagne :)

37voto

Felipe Points 927

Puisqu’il est possible que les gens visitent toujours ici et sera biaisée contre Regex après les benchmarks... Donc je vais donner une version actualisée de la valeur de référence, avec une version compilée de l’expression régulière. Qui s’oppose aux repères précédents, celui-ci montre Regex solution a fait toujours de bonnes performances.

Copiés à partir de Bill le lézard et mis à jour avec la version compilée :

Résultats :

24voto

Jon Skeet Points 692016

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 pourriez faire ce peu à la main aussi, mais il serait beaucoup plus compliqué.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X