Dois-je utiliser string.isEmpty () ou «» .equals (string)?


171

Le titre dit tout. Je teste généralement cela avec un string == null, donc je ne suis pas vraiment préoccupé par un test de sécurité nulle. Lequel dois-je utiliser?

String s = /* whatever */;
...
if (s == null || "".equals(s))
{
    // handle some edge case here
}

ou

if (s == null || s.isEmpty())
{
    // handle some edge case here
}

Sur cette note - fait isEmpty()même autre chose que return this.equals("");ou return this.length() == 0;?


26
Gardez à l'esprit qu'il isEmpty()s'agit uniquement de Java 6+.
ColinD le

1
Vous pouvez créer une méthode d'assistance Util.String.hasValue (String s) qui vérifie la valeur NULL, la vacuité et les espaces pour gérer tous les cas.
Cloudanger

5
@ColinD Probablement pas un problème - J2SE 5.0 a terminé sa période de fin de vie il y a quelque temps.
Tom Hawtin - tackline

1
Une autre chose à considérer est "" .equals () prend Object comme argument, donc vous n'obtiendrez pas une erreur du compilateur si le type d'argument change de String à autre chose, pour le meilleur ou pour le pire.
Paul Jackson

Réponses:


251

Le principal avantage de "".equals(s)est que vous n'avez pas besoin de la vérification de null ( equalsvérifiera son argument et retournera falses'il est nul), ce dont vous semblez ne pas vous soucier. Si vous n'êtes pas inquiet d' sêtre nul (ou si vous le vérifiez autrement), j'utiliserais certainement s.isEmpty(); il montre exactement ce que vous vérifiez, vous vous souciez de savoir si sc'est vide ou non , pas si cela équivaut à la chaîne vide


29
Merci pour l'explication. Maintenant je sais pourquoi favoriser "" .equals (str) sur str.equals ("")! Je me demandais toujours pourquoi les autres l'utilisaient si souvent, mais je ne tenais pas compte des valeurs nulles. Super :-)
Peter Wippermann

10
À mon humble avis, la vérification null est toujours nécessaire dans les exemples ci-dessus car nous supposons que la condition doit être vraie pour une valeur nulle. s == null || "" .equals (s)
mkorpela

5
@ Master.Aurora non, si getValue()retourné null, vous obtiendrez une NullPointerException lors de l' toString()appel
ataulm

12
@RenniePet Ce n'est pas comme s'il y avait de la magie. Si sest null, vous ne pouvez pas appeler de méthodes dessus - il est nul. ""ne sera jamais nul, vous pouvez donc appeler des méthodes dessus en toute sécurité et equals()pouvez gérer le cas où son argument est nul
Michael Mrozek

5
Une note sur les performances: isEmpty()vérifie la longueur interne d'un tableau privé alors que equals(Object anObject)fait beaucoup plus (par exemple, vérification instanceof). En termes de performances, isEmpty()est généralement plus rapide.
Turing85

82

String.equals("")est en fait un peu plus lent qu'un simple isEmpty()appel. Les chaînes stockent une variable de comptage initialisée dans le constructeur, car les chaînes sont immuables.

isEmpty() compare la variable count à 0, tandis que equals vérifie le type, la longueur de la chaîne, puis effectue une itération sur la chaîne à des fins de comparaison si les tailles correspondent.

Donc, pour répondre à votre question, vous isEmpty()en ferez beaucoup moins! et c'est une bonne chose.


3
Je pense que dans ce cas, la différence ne s'applique pas; il n'y aura jamais d'itération sur les chaînes à des fins de comparaison, car les tailles ne correspondent pas (à moins que la chaîne ne soit réellement vide et qu'il n'y ait pas de caractères à parcourir)
Michael Mrozek

2
Vrai mais avec des égaux, vous devez d'abord vérifier les références pour voir s'il s'agit du même objet, puis une instanceof, puis une conversion en String, une vérification de la longueur, et enfin l'itération. Si les deux chaînes étaient vides, alors ce ne serait qu'une simple vérification de référence.
David Young

le code source de la classe String est disponible java2s.com/Open-Source/Java-Document/6.0-JDK-Core/lang/java/…
David Young


17

Une chose que vous voudrez peut - être envisager d' ailleurs les autres questions mentionnées est que isEmpty()a été introduit en 1.6, donc si vous l' utilisez, vous ne serez pas en mesure d'exécuter le code sur Java 1.5 ou ci - dessous.


4
Ce n'est certainement pas une préoccupation pour moi.
Matt Ball

1
De plus, cette réponse remonte à 6 ans. J'espère que personne n'a plus besoin d'utiliser quelque chose d'ancien comme Java 1.5.
Misha Nasledov le

1
Il y a en fait beaucoup de choses qui peuvent casser lors de la mise à jour d'une version java. C'est moins critique pour une application back-end qui s'exécute sur un gros serveur, mais c'est important pour les applications clientes. Les bibliothèques graphiques et les stratégies de garbage collection sont souvent affectées par les mises à niveau majeures et mineures de Java. En plus de cela, le logiciel client peut fonctionner sur différents systèmes d'exploitation et parfois avec une mémoire limitée, ce qui signifie que vous n'aurez souvent pas le budget / les ressources pour tout tester. - Oui, j'ai des clients qui s'en tiennent toujours à Java 5 en 2017.
bvdb


2

Cela n'a pas vraiment d'importance. "".equals(str)est plus clair à mon avis.

isEmpty()retourne count == 0;


47
Je dirais que str.isEmpty()c'est beaucoup plus clair que "".equals(str). Il se lit comme ce que vous vérifiez. Question d'opinion cependant, je suppose.
ColinD le

7
Je pense que certaines personnes préfèrent faire "" .equals (str) pour éviter les NPE. Personnellement, je n'aime pas ça parce que je préfère vérifier que la chaîne n'est pas nulle en premier.
CoolBeans

2

J'ai écrit une classe de testeur qui peut tester les performances:

public class Tester
{
    public static void main(String[] args)
    {
        String text = "";

        int loopCount = 10000000;
        long startTime, endTime, duration1, duration2;

        startTime = System.nanoTime();
        for (int i = 0; i < loopCount; i++) {
            text.equals("");
        }
        endTime = System.nanoTime();
        duration1 = endTime - startTime;
        System.out.println(".equals(\"\") duration " +": \t" + duration1);

        startTime = System.nanoTime();
        for (int i = 0; i < loopCount; i++) {
            text.isEmpty();
        }
        endTime = System.nanoTime();
        duration2 = endTime - startTime;
        System.out.println(".isEmpty() duration "+": \t\t" + duration2);

        System.out.println("isEmpty() to equals(\"\") ratio: " + ((float)duration2 / (float)duration1));
    }
}

J'ai trouvé que l'utilisation de .isEmpty () prenait environ la moitié du temps de .equals ("").


Ce n'est pas un microbenchmark valide. Je recommanderais fortement d'utiliser Caliper ou un outil d'analyse comparative similaire. stackoverflow.com/q/504103/139010
Matt Ball

Merci pour le conseil! Quand j'aurai du temps libre, j'expérimenterai des micro-analyses comparatives et je mettrai à jour ma réponse.
conapart3
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.