Je dois faire une série de vérifications nulles (vérifications nulles imbriquées) pour obtenir un tableau de chaînes comme ci-dessous
String[] test; if(CollectionUtils.isNotEmpty(checkList)){ if(MapUtils.isNotEmpty(checkList.get(0))){ if(StringUtils.isNotBlank(checkList.get(0).get("filename"))){ test = checkList.get(0).get("filename").split("_"); } } }
Y a-t-il une meilleure façon, peut-être en utilisant Java8 facultatif, d'effectuer ce genre de chèques imbriqués? J'ai essayé sans succès d'utiliser Optional avec flatmap / map.
3 Réponses :
Si checkList est nul, il lèvera une exception de pointeur nul sur CollectionUtils.isNotEmpty (checkList). Utilisez également un vérificateur vide intégré. Mieux vaut coder
if (null != checkList && !checkList.isEmpty() && null != checkList.get(0) && !checkList.get(0).isEmpty() && StringUtils.isNotBlank(checkList.get(0).get("filename"))) { test = checkList.get(0).get("filename").split("_"); }
Vous pouvez utiliser une longue chaîne d'opérations facultatives
et Stream
pour transformer l'entrée étape par étape en sortie. Quelque chose comme ça (non testé):
String[] test = checkList.stream() .findFirst() .map(m -> m.get("filename")) .map(f -> f.split("_")) .orElse(null);
Je vous encourage fortement à arrêter d'utiliser les listes et les cartes null
. Il est préférable d'utiliser des collections vides plutôt que des collections nulles , de cette façon, vous n'avez pas besoin d'avoir des vérifications nulles partout. De plus, n'autorisez pas les chaînes vides ou vides dans vos collections; filtrez-les ou remplacez-les par null
tôt, dès que vous convertissez l'entrée utilisateur en objets en mémoire. Vous ne voulez pas avoir à insérer des appels à trim ()
et isBlank ()
et autres partout.
Si vous l'avez fait que vous pourriez simplifier en:
String[] test = Optional.ofNullable(checkList) .map(Collection::stream) .orElseGet(Stream::empty) .findFirst() .map(m -> m.get("filename")) .filter(f -> !f.trim().isEmpty()) .map(f -> f.split("_")) .orElse(null);
Bien mieux, non?
Merci. Je suis d'accord pour ne pas utiliser de listes et de cartes nulles - mais ... Je reçois ces données d'une autre partie du système et je n'en ai donc pas le contrôle. Je vais essayer ce qui précède avec cette hypothèse et voir si cela fonctionne pour moi
Le premier a bien fonctionné. Pour le second, j'essaie de travailler avec l'équipe qui génère la liste pour voir s'ils peuvent faire le changement pour s'assurer d'envoyer des listes vides ou des cartes au lieu de null. Le second a également travaillé sur le testcase où je me suis assuré ne pas avoir de valeurs nulles dans les données reçues.
Ne pas imbriquer les if
, mais simplement les déballer et les inverser:
public static String[] unwrap(List<Map<String, String>> checkList) { ... }
Bien que cela ne fonctionne que lorsque vous enveloppez cette logique d'extraction dans une méthode:
String[] defaultValue = // let this be what ever you want if(checkList == null || checkList.isEmpty()) { return defaultValue; } Map<String, String> map = checkList.get(0); if(map == null || map.isEmpty()) { return defaultValue; } String string = map.get("filename"); if(string == null || string.trim().isEmpty()) { return defaultValue; } return string.split("_");
Je pensais que
! CheckList.isEmpty ()
renverrait un NPE. Je pensais que je devrais fairecheckList! = Null &&! CheckList.isEmpty ()
, j'ai donc utilisé l'autre bibliothèque. Donc, pour cette vérification, dois-je avoir les instructionsif ()
imbriquées?Quelque chose comme
return Optional.ofNullable (checkList) .filter (l ->! L.isEmpty ()) .map (l -> l.get (0)) .filter (m ->! M.isEmpty () ) .map (e -> e.getOrDefault ("filename", "") .split ("_")) .orElse (new String [10]);
qui n'est pas bon sauf si vous savez, pourquoi les valeurs codées en dur flottent.Ne laissez pas les références de collection être
nulles
en premier lieu. Ensuite, vous n'avez pas besoin de méthodes tierces pour effectuer des vérificationsnull
.