J'essaie de vérifier si une chaîne Java n'est pas null
, ni vide ni espace.
Dans mon esprit, ce code aurait dû être tout à fait à la hauteur de la tâche.
public static boolean isEmpty(String s) {
if ((s != null) && (s.trim().length() > 0))
return false;
else
return true;
}
Selon la documentation, String.trim()
devrait fonctionner ainsi:
Retourne une copie de la chaîne, en omettant les espaces de début et de fin.
Si cet objet
String
représente une séquence de caractères vide ou si les premier et dernier caractères de la séquence de caractères représentée par cet objetString
ont tous deux un code supérieur à'\u0020'
(le caractère espace), une référence à cet objetString
est renvoyée.
Cependant, Apache/commons/lang/StringUtils.Java
le fait un peu différemment.
public static boolean isBlank(String str) {
int strLen;
if (str == null || (strLen = str.length()) == 0) {
return true;
}
for (int i = 0; i < strLen; i++) {
if ((Character.isWhitespace(str.charAt(i)) == false)) {
return false;
}
}
return true;
}
Selon la documentation, Character.isWhitespace()
:
Détermine si le caractère spécifié est un espace blanc conformément à Java. Un caractère est un caractère d'espacement Java si et seulement si il répond à l'un des critères suivants:
- Il s'agit d'un caractère d'espace Unicode (
SPACE_SEPARATOR
,LINE_SEPARATOR
ouPARAGRAPH_SEPARATOR
), mais il ne s'agit pas également d'un espace insécable ('\u00A0'
,'\u2007'
,'\u202F'
).- Il s'agit de
'\t'
, U + 0009 TABULATION HORIZONTALE.- C'est
'\n'
, U + 000A LINE FEED.- C'est
'\u000B'
, U + 000B TABULATION VERTICALE.- C'est
'\f'
, U + 000C FORM FEED.- Il s'agit de
'\r'
, U + 000D CARRIAGE RETURN.- Il s'agit de
'\u001C'
, U + 001C SEPARATOR FILE.- C'est
'\u001D'
, U + 001D GROUP SEPARATOR.- C'est
'\u001E'
, U + 001E RECORD SEPARATOR.- C'est
'\u001F'
, U + 001F UNIT SEPARATOR.
Si je ne me trompe pas - ou peut-être je ne le lis pas correctement - la String.trim()
devrait supprimer tous les caractères vérifiés par Character.isWhiteSpace()
. Tous voient au-dessus de '\u0020'
.
Dans ce cas, la fonction isEmpty
plus simple semble couvrir tous les scénarios que couvre la plus longue isBlank
.
isEmpty
et isBlank
se comportent différemment dans un scénario de test?isBlank
et ne pas utiliser isEmpty
?Pour les personnes intéressées par l'exécution d'un test, voici les méthodes et les tests unitaires.
public class StringUtil {
public static boolean isEmpty(String s) {
if ((s != null) && (s.trim().length() > 0))
return false;
else
return true;
}
public static boolean isBlank(String str) {
int strLen;
if (str == null || (strLen = str.length()) == 0) {
return true;
}
for (int i = 0; i < strLen; i++) {
if ((Character.isWhitespace(str.charAt(i)) == false)) {
return false;
}
}
return true;
}
}
Et des tests unitaires
@Test
public void test() {
String s = null;
assertTrue(StringUtil.isEmpty(s)) ;
assertTrue(StringUtil.isBlank(s)) ;
s = "";
assertTrue(StringUtil.isEmpty(s)) ;
assertTrue(StringUtil.isBlank(s));
s = " ";
assertTrue(StringUtil.isEmpty(s)) ;
assertTrue(StringUtil.isBlank(s)) ;
s = " ";
assertTrue(StringUtil.isEmpty(s)) ;
assertTrue(StringUtil.isBlank(s)) ;
s = " a ";
assertTrue(StringUtil.isEmpty(s)==false) ;
assertTrue(StringUtil.isBlank(s)==false) ;
}
Mise à jour: La discussion a été très intéressante - et c’est la raison pour laquelle j’adore Stack Overflow et les gens d’ici. En passant, pour revenir à la question, nous avons eu:
isBlank()
standard. Merci @devconsole. Existe-t-il une chaîne qui fera que
isEmpty
etisBlank
se comportent différemment dans un scénario de test?
Notez que Character.isWhitespace
peut reconnaître les caractères Unicode et renvoyer true
pour les caractères Unicode.
Détermine si le caractère spécifié est un espace blanc conformément à Java. Un caractère est un caractère d'espacement Java si et seulement si il répond à l'un des critères suivants:
Il s'agit d'un caractère d'espace Unicode (
SPACE_SEPARATOR
,LINE_SEPARATOR
ouPARAGRAPH_SEPARATOR
), mais il ne s'agit pas également d'un espace insécable ('\u00A0'
,'\u2007'
,'\u202F'
).
[...]
De même, la méthode trim()
supprime tous les caractères de contrôle dont les points de code sont inférieurs à U + 0020 et le caractère d'espacement (U + 0020).
Par conséquent, les deux méthodes se comporteraient différemment en présence d'un caractère d'espacement Unicode. Par exemple: "\u2008"
. Ou lorsque la chaîne contient des caractères de contrôle qui ne sont pas considérés comme des espaces par la méthode Character.isWhitespace
. Par exemple: "\002"
.
Si vous deviez écrire une expression régulière pour le faire (ce qui est plus lent que de faire une boucle dans la chaîne et de vérifier):
isEmpty()
serait équivalent à .matches("[\\x00-\\x20]*")
isBlank()
serait équivalent à .matches("\\p{javaWhitespace}*")
(Les méthodes isEmpty()
et isBlank()
autorisent toutes deux la référence null
String. Elle n'est donc pas exactement équivalente à la solution regex, mais elle est équivalente, à part ça).
Notez que \p{javaWhitespace}
, comme son nom l'indique, est une syntaxe spécifique à Java pour accéder à la classe de caractères définie par la méthode Character.isWhitespace
.
En supposant qu'il n'y en ait pas, y a-t-il une autre considération à cause de laquelle je devrais choisir
isBlank
et ne pas utiliserisEmpty
?
Ça dépend. Cependant, je pense que l'explication dans la partie ci-dessus devrait être suffisante pour que vous décidiez. Pour résumer la différence:
isEmpty()
considérera que la chaîne est vide si elle ne contient que des caractères de contrôle1 en dessous de U + 0020 et du caractère espace (U + 0020)
isBlank
considérera que la chaîne est vide si elle ne contient que des caractères d'espacement, tels que définis par la méthode Character.isWhitespace
, qui inclut des caractères d'espacement Unicode.
1 Il y a aussi le caractère de contrôle à U+007F DELETE
, qui n'est pas coupé par la méthode trim()
.
Les deux méthodes standard ont pour objet de distinguer ces deux cas:
org.Apache.common.lang.StringUtils.isBlank(" ")
(retournera true).
org.Apache.common.lang.StringUtils.isEmpty(" ")
(retournera false).
Votre implémentation personnalisée de isEmpty()
renverra true.
METTRE À JOUR:
org.Apache.common.lang.StringUtils.isEmpty()
est utilisé pour rechercher si la chaîne a une longueur de 0 ou une valeur nulle.
org.Apache.common.lang.StringUtils.isBlank()
fait un pas en avant. Il vérifie non seulement si la chaîne a une longueur de 0 ou une valeur nulle, mais également s'il s'agit uniquement d'une chaîne d'espaces.
Dans votre cas, vous coupez la chaîne dans la méthode votreisEmpty
. La seule différence qui peut se produire maintenant ne peut pas se produire (le cas où vous lui donnez " "
) car vous êtes rognage it (supprimer le blanc final - ce qui revient à supprimer tous les espaces).
Je choisirais isBlank()
à isEmpty()
car trim()
crée un nouvel objet String qui doit être nettoyé ultérieurement. isBlank()
, d'autre part, ne crée aucun objet.
Vous pouvez jeter un oeil à JSR 303 Bean Validtion qui contient les annotatinos @NotEmpty
et @NotNull
. Bean Validation est cool parce que vous pouvez séparer les problèmes de validation de l'intention initiale de la méthode.
Pourquoi ne pouvez-vous pas simplement utiliser un opérateur ternaire imbriqué pour y parvenir? Consultez le code exemple public static void main(String[] args)
{
String s = null;
String s1="";
String s2="hello";
System.out.println(" 1 "+check(s));
System.out.println(" 2 "+check(s1));
System.out.println(" 3 "+check(s2));
}
public static boolean check(String data)
{
return (data==null?false:(data.isEmpty()?false:true));
}
et la sortie est comme suit
1 faux 2 faux 3 vrai
ici, le premier 2 scénarios renvoie faux (c'est-à-dire nul et vide) et le troisième scénario renvoie vrai
<%
System.out.println(request.getParameter("userName")+"*");
if (request.getParameter("userName").trim().length() == 0 | request.getParameter("userName") == null) { %>
<jsp:forward page="HandleIt.jsp" />
<% }
else { %>
Hello ${param.userName}
<%} %>
Ce code simple fera assez:
public static boolean isNullOrEmpty(String str) {
return str == null || str.trim().equals("");
}
Et les tests unitaires:
@Test
public void testIsNullOrEmpty() {
assertEquals(true, AcdsUtils.isNullOrEmpty(""));
assertEquals(true, AcdsUtils.isNullOrEmpty((String) null));
assertEquals(false, AcdsUtils.isNullOrEmpty("lol "));
assertEquals(false, AcdsUtils.isNullOrEmpty("HallO"));
}
Avec Java 8, vous pouvez également utiliser la fonctionnalité Facultatif avec le filtrage. Pour vérifier si une chaîne est vide, le code est purement Java SE sans bibliothèque supplémentaire . Le code suivant illustre une implémentation isBlank ().
!Optional.ofNullable(tocheck).filter(e -> e != null && e.trim().length() > 0).isPresent()
Optional.ofNullable(toCheck)
.filter(e ->
{
int strLen;
if (str == null || (strLen = str.length()) == 0) {
return true;
}
for (int i = 0; i < strLen; i++) {
if ((Character.isWhitespace(str.charAt(i)) == false)) {
return false;
}
}
return true;
})
.isPresent()