J'ai une liste de classe de personne
int nameFlag = 0; int idFlag = 0; for (Person person : personList) { if(person.getName() != null){ nameFlag++; } if(person.getId() != null){ idFlag++; } } if(nameFlag >= 1 && idFlag >= 1){ throw new Exception("Please pass name only or id only, not both"); }
Les utilisateurs peuvent transmettre l'entrée de plusieurs personnes sous forme de liste, comme indiqué ci-dessous.
[ { "name": "test" }, { "id": "102" } ]
Pouvons-nous utiliser le flux java-8
ici?
3 Réponses :
Pourquoi ne pas le faire échouer rapidement au lieu de parcourir toute la liste.
boolean isIdPresent = false; boolean isNamePresent = false; for (Person person : personList) { if (person.getId() != null) { isIdPresent = true; } if (person.getName() != null) { isNamePresent = true; } if (isIdPresent && isNamePresent) { throw new Exception("Both Present"); } }
Merci pour votre réponse. Mais que se passe-t-il si le nom et l'identifiant sont présents sur des objets différents ?. Ce code ne fonctionnera pas dans ce cas. Cela ne fonctionnera que si le même objet a un nom et un identifiant
si vous passez une liste de personnes uniquement avec des identifiants ou uniquement avec des noms, cela ne lèvera aucune exception. Cela lèvera une exception uniquement lorsque vous avez un mélange d'objets.
Vous ne savez pas pourquoi vous devez construire des objets Person
de cette façon, mais vous pouvez essayer ceci -
List<Map<String,Object>> values = objectMapper.readValue(input, ArrayList.class); boolean valid = values.stream() .map(Map::keySet) .collect(Collectors.toSet()) .size() == 1;
Merci pour votre réponse. En fait, ce n'est qu'un exemple basé sur mon code. J'ai des exigences similaires, j'ai donc posé la question en utilisant la classe Person.
Essayez-le et faites-moi savoir si cela fonctionne pour vous.
Je mettrai en œuvre chacune des réponses dans mon projet, accepterai la réponse la mieux adaptée au projet.
vous pouvez créer une classe d'assistance et utiliser la réduction sur la liste:
class CountPair { int nameCount = 0; int idCount = 0; CountPair sum(CountPair countPair) { nameCount += countPair.nameCount; idCount += countPair.idCount; return this; } CountPair plus(Person person) { idCount += person.getId() == null ? 0 : 1; nameCount += person.getName() == null ? 0 : 1; return this; } }
et la classe CountPair
:
CountPair reduce = personList.stream() .reduce(new CountPair(), CountPair::plus, CountPair::sum); if(reduce.idCount > 0 && reduce.nameCount > 0) { //throw exception }
pour un type primitif, cela n'a pas vraiment de sens de comparer
if (person.getId ()! = null)
, non?oui @Naman, Merci de l'avoir notifié, ça devrait être Long.
..et avec les flux, il n'y a pas un moyen aussi propre que vous l'avez écrit avec l'approche impérative de compter les deux attributs et de valider. vous pouvez bien sûr diffuser deux fois pour compter chaque attribut, mais alors pourquoi voudriez-vous faire cela? Ce serait quelque chose comme
long nameFlag = personList.stream (). Map (Person :: getName) .filter (java.util.Ob jects :: nonNull) .coun t (); long idFlag = personList.stream (). map (Person :: getId) .filter (java.util.Obje cts :: nonNull) .count ();
puis validez ..oui, nous avons cette option, mais est-ce un bon moyen d'utiliser une opération de flux deux fois qu'une seule boucle for? Je n'en suis vraiment pas sûr?
Je suis vraiment confus sur ce que je dois suivre? Fonctionnement en boucle unique ou en flux multiples, pour des performances optimales
L'utilisation de deux flux signifierait une itération deux fois sur la collection, ce n'est donc certainement pas efficace sur une seule itération. Je recommanderais de rester avec votre approche actuelle plutôt que de choisir de passer aux flux pour cela.