12
votes

Quelle est la meilleure façon de vérifier si une chaîne est vide que d'utiliser string.trim (). Longueur () dans Java 5/6?

Il y a probablement une méthode pour renvoyer l'index du premier caractère non vide dans une chaîne en Java5 / 6. Mais je ne peux plus le trouver. Un outil de réponse de code dit qu'il vaut mieux que de vérifier string.trim (). Longueur () .


17 commentaires

Qu'en est-il d'itération sur les caractères jusqu'à la fin de la chaîne ou du caractère non vide?


Je fais toujours exactement couper (). Longueur (), et ne perdez pas mon sommeil sur une telle inefficacité mineure.


Est-ce que votre outil magique dit, pourquoi c'est mieux? Peut-être qu'il vaut mieux ignorer cette suggestion;)


Parce que Trim () crée une nouvelle instance de chaîne (), je suppose.


@road à Yambourg: vous êtes absolument correct. Il n'y a aucune raison de commencer à se soucier des problèmes de performance de cette échelle ... Vous perdrez votre temps au mieux et au pire des cas, vous pourriez finir de ne pas vérifier ce dont vous avez besoin. Il suffit de commenter que vous assurez que la chaîne n'est pas tous des espaces, puis découpez la longueur () et vérifiez la longueur.


Bon gars, je l'ai trouvé enfin des règles PMD de inefficienttyStringCheck : Depuis: PMD 3.6 string.trim (). La longueur () est un moyen inefficace de vérifier si une chaîne est vraiment vide, car elle crée un nouvel objet de chaîne simplement pour vérifier sa taille. Envisagez de créer une fonction statique qui boucle via une chaîne, vérifiant caractère.iswitespace () sur chaque caractère et renvoyant false si un caractère non-espaces est trouvé.


@road à Yambourg à droite, mais c'est en fait une très petite inefficacité, car la nouvelle chaîne est créée à l'aide de la méthode de sous-chaîne , et donc il partage le stockage de caractères (le Valeur champ) avec l'original chaîne .


Il partage le stockage de caractères, mais l'instance de chaîne elle-même est allouée dans le tas. Pour un grand nombre de chèques, il fait beaucoup de fragments.


@road: trim () renvoie une nouvelle chaîne seulement Si son contenu est différent de la chaîne On a appelé Sur, sinon, il se retourne (c'est même documenté pour que vous puissiez compter dessus!). Donc, la nouvelle string est uniquement créée dans le cas (généralement rare) où il y a un espace au début ou à la fin de la chaîne .


Habituellement rare? Cela dépend beaucoup des données. Pour certaines entrées, les espaces de fuite sont courants.


En dehors de cela: les objets de courte durée ne causent pas beaucoup de problèmes à la JVM. Et vous ne pouvez pas obtenir beaucoup plus de courte durée que la "chaîne moyenne" dans foo.trim (). Isempty () .


@road à Yambourg - Le problème de la fragmentation dépendra de ce que GC le JVM est configuré pour utiliser.


La concaténation de la chaîne m'a causé 10x fois retard dans le traitement de la demande; n'avait que des chaînes de courte durée. StringBuilder est inventé pour une cause. Pareil ici.


@Stephen C: La fragmentation peut être perceptible ou non, mais cela se produira. Si cela peut être évité, pourquoi pas? (En plus, je, si vous lisez mon premier commentaire, faites exactement couper (). longueur () - parce que dans mes applications, cette inefficacité n'a pas d'importance).


@road: C'est un problème tout à fait un problème différent. Si la cordon-concaténation ralentit votre code, il s'agit de la copie répétée (inutile) des tableaux de caractères qui vous ralentissent. C'est pas "fragmentation de tas".


J'ai utilisé des mots "fragmentation de tas" seulement pour sonner plus intelligemment. Ça m'arrive. Ce que je voulais dire, c'est que l'allocation inutile donne des travaux supplémentaires, inutiles, au GC, qui peuvent être facilement évités.


@road: Si par "facilement", vous voulez dire "en introduisant une nouvelle méthode qui remplace un idiome bien connu que tous ceux qui lit le code devront vérifier avant de savoir ce que le code fait réellement", alors oui. ;-) Désolé, ce n'est pas signifié comme sarcastique que cela semble probablement. Je veux juste rappeler à tous que le temps de développeur est généralement (encore ce mot dangereux!) Plus cher que les quantités minuscules de la durée de la CPU.


10 Réponses :


2
votes

Java 6 a introduit string.isempty () , vous pouvez donc l'utiliser conjointement avec string.trim () . Vous pouvez également utiliser des expressions régulières, par exemple en utilisant une telle condition: ! Str.matches ("\\ s *") .


2 commentaires

Le problème est de la garniture (). Il crée (ou peut créer une nouvelle instance de chaîne) qui n'est pas efficace.


@Vladimirdyuzhev C'est ce à quoi je m'attendrais, mais PMD a cessé de la signaler lorsque je me suis passé à .Impty () au lieu de .length () == 1, même si j'ai gardé .trim () dans



8
votes

J'utiliserais le GUAVA charmatcher classe: xxx


5 commentaires

Peut-être S.Matches ("\\ s *"); ferait la même chose alors? Personnellement, je préfère coller à Jre Libs dans la mesure du possible ...


@road: En pratique: Oui, ce sera la même chose. Strictement parlant, il ne teste que un sous-ensemble limité de caractères blancheurs, tandis que charmatcher.whitSpace contient tous les caractères blancheurs Unicode. De plus, .Matches () nécessiterait de compiler la regex à chaque fois, ce qui pourrait être plus lent.


Pas sûr que "\\ s" correspond à un sous-ensemble limité. Et REGEXP - Je peux la compiler une fois et utiliser dans une méthode utilitaire Stringutils.isblank (s).


@road: selon motif < / Code> Il correspond à [\ t \ n \ x0b \ f \ r] . Cela signifie que de nombreux autres caractères blanchisseurs tels que U + 200A , u + 202f , U + 3000 , ... ne sont pas détectés). Je ne sais pas combien de différence qui fera dans la pratique, cependant.


Oui, il suffit de lire des docs là-bas et là-bas. Besoin de déposer un bug pour SU ... Oracle, je veux dire! :)



-4
votes

(meilleur moyen) string.equals ("")

mais aussi, xxx


3 commentaires

string.length () == 0 est FAR plus efficace que string.equals ("")


Pas vraiment une solution pour les cordes avec des espaces blousins ​​uniquement.


String.equals (NULL) retourne toujours faux ou jette NullpointException.



0
votes

Il existe une méthode dans la chaîne pour cet objectif exact.

String emptyString = "";
emptyString.isEmpty();


1 commentaires

Mais ce n'est pas la même chose que string.trim (). Longueur () == 0 ! Changez simplement votre première ligne en String videytring = "\ n" . Votre code reviendra FALSE, tandis que string.trim (). Longueur () == 0 retournera true.



13
votes

J'aime toujours utiliser la bibliothèque Apache Commons Stringutils. Il a Isefty () et est Isblank () qui gère WhitSpace.

http: //commons.apache. Org / lang / API-2.5 / ORG / Apache / Commons / Lang / StringUTILS.HTML

Sans oublier les nombreuses autres méthodes utiles de cette classe et la bibliothèque en général.


3 commentaires

(appris de @ Joachim Sauer) ne prend pas en charge tout Unicode alors que le charmatcher le fait! ;)


Si vous vous référez à ses commentaires ci-dessous 2 des 3 caractères Unicode, il répertorie le travail avec Stringutils. Sauf si je fais quelque chose de mal, stringutils.isblank ((caractère.tostring ('\ u200a'))); renvoie true et isempty renvoie false qui devrait être correcte. Même chose pour \ u3000. \ U202f n'est pas considéré vide par le personnage Java .iswhiteespace donc je ne suis pas sûr que je souhaiterais que les Stringutiliens reviennent vrai pour cela.


Stringutils.Impty () ne coupe pas la corde depuis v2. De Javadoc: "Remarque: cette méthode a changé dans la version 2.0 de Lang. Il ne coupe plus la chaîne. Cette fonctionnalité est disponible dans Isblank ()." COMMONS.APACHE.ORG/PROPER/COMMONS-LANG/JAVADOCS/API-2.6/ORG/ ...



1
votes

Si vous souhaitez tester une chaîne qui a une longueur de zéro que d'utiliser isempty () ou longueur () == 0 est le meilleur moyen.

Si vous souhaitez tester si la chaîne ne contient que des espaces blancs, la recherche du premier caractère non-blanchissace est plus efficace car l'objet intermédiaire n'est pas créé (comme avec Couper () )

Mais dans tous les cas, je recommande également les Commons d'Apache Stringutitils.Impty () car il résume bien tout cela.


0 commentaires

2
votes

Si vous souhaitez tester, si cela ne contient que des caractères blancheurs, vous pouvez utiliser Regex

string.matches("\\s*")


0 commentaires

5
votes

Bon gars, je l'ai trouvé enfin des règles PMD de inefficientemptystringcheck : < / p>

InefficientemptyStringCheck:
Depuis: PMD 3.6
String.trim (). La longueur () est un manière inefficace de vérifier si une chaîne est vraiment vide, car cela crée un nouveau Objet de chaîne juste pour vérifier sa taille. Envisager de créer une fonction statique qui boucle à travers une corde, vérifiant Caractère.iswhiteespace () sur chacun caractère et retourner faux si un le caractère non-blouse est trouvé.

Ce n'est qu'une suggestion de PMD. L'adopter ou non dépend de la priorité: l'efficacité des programmes ou le temps des programmeurs.


0 commentaires

-1
votes

Essayez xxx


0 commentaires

3
votes

Java 11 introduit la méthode "isBlank". Voir https://docs.oracle.com/fr/java/javase/11/docs/api/java.base/java/lang/string.html#isblank ()

retourne true si la chaîne est vide ou contient uniquement des pointe de code d'espace blanc, sinon false.


0 commentaires