Je souhaite utiliser une seule instruction avec les flux Java.
Je veux filtrer tous les objets Servicework, où les exigences sont "vraies", puis vérifier si tous les objets Servicework ont le statut "Terminé".
Mais si le serviceworkList est vide, alors la variable "validate" est fausse. Je connais la spécification de allMatch, que si la liste est vide, alors le retour est vrai.
Des suggestions sur la façon dont je pourrais reconstruire le flux, que si la liste est vide, j'aurais faux?
enum Status { DONE, NOT_DONE }
class ServiceWork { private Status status; private boolean isRequirement; public Status getStatus() { return status; } public void setStatus(Status status) { this.status = status; } public boolean isRequirement() { return isRequirement; } public void setRequirement(boolean requirement) { isRequirement = requirement; } }
public class Service{ List<ServiceWork> serviceWorkList = new ArrayList<>(); boolean validate = serviceWorkList .stream() .filter(ServiceWork::isRequirement) .allMatch(a -> a.getStatus() == Status.DONE); }
3 Réponses :
Ajoutez simplement une vérification supplémentaire que la liste n'est pas vide:
Set<Status> status = serviceWorkList .stream() .filter(ServiceWork::isRequirement) .map(ServiceWork::getStatus()) .collect(Collectors.toCollection(() -> EnumSet.noneOf(Status.class))); boolean validate = status.remove(Status.DONE) == Status.DONE && status.isEmpty();
Après votre commentaire, vous pouvez utiliser ceci:
boolean validate = !serviceWorkList.isEmpty() && serviceWorkList .stream() .filter(ServiceWork::isRequirement) .allMatch(a -> a.getStatus() == Status.DONE);
Il rassemble d'abord tous les statuts dans un EnumSet
, puis supprime Status.DONE
de l'ensemble et si l'ensemble est vide, chaque élément a getStatus () == Status.DONE
.
Cela supprime le court-circuit, donc il continuera à itérer sur la serviceWorkerList
même si un Status
autre que Status.DONE
a été rencontré
je veux dire s'il n'y a pas d'élément correspondant au prédicat ServiceWork :: isRequirement
Stream.allMatch () retournera toujours vrai pour une liste vide
Vous devriez ajouter une autre validation, comme
boolean validate = !serviceWorkList.isEmpty() && serviceWorkList .stream() .filter(ServiceWork::isRequirement) .allMatch(a -> a.getStatus() == Status.DONE);
je veux dire s'il n'y a pas d'élément correspondant au prédicat ServiceWork :: isRequirement
Il ne sera pas pratique de faire votre validation complète en une seule opération de flux. Je suggère deux opérations de flux:
boolean allRequirementsDone = serviceWorkList.stream() .filter(ServiceWork::isRequirement) .allMatch(a -> a.getStatus() == Status.DONE); boolean atLeastOneRequirement = serviceWorkList.stream() .anyMatch(ServiceWork::isRequirement); boolean validate = allRequirementsDone && atLeastOneRequirement;
Voulez-vous dire "si
serviceWorkList
est vide" ou "s'il n'y a aucun élément correspondant au prédicatServiceWork :: isRequirement
"?@Holger: je veux dire s'il n'y a pas d'élément correspondant au prédicat
serviceWorkList .stream () .filter (ServiceWork :: isRequirement) .map (a -> a.getStatus () == Status.DONE) .reduce (Boolean :: logicalAnd) .orElse (false); code >
Vérifiez ceci stackoverflow.com/a/56744122/6505418
Ressemble à un double de stackoverflow.com/questions/46075776