Как вернуть false для пустого списка при использовании Stream.allMatch ()? - PullRequest
2 голосов
/ 15 марта 2019

Я хочу использовать один оператор с потоками Java.

Я хочу отфильтровать все объекты Servicework, где требования «истинны», а затем проверить, все ли объекты Servicework имеют статус «Выполнено».

Но если serviceworkList пуст, то переменная validate равна false. Я знаю спецификацию allMatch, что если список пуст, то возвращаемое значение равно true.

Любые предложения о том, как я мог бы перестроить поток, что если список не будет пустым, я получу false?

public class Service{

    List<ServiceWork> serviceWorkList = new ArrayList<>();


    boolean validate = serviceWorkList
        .stream()
        .filter(ServiceWork::isRequirement)
        .allMatch(a -> a.getStatus() == Status.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;
    }
}

enum Status {
    DONE, NOT_DONE
}

Ответы [ 3 ]

8 голосов
/ 15 марта 2019

Просто добавьте дополнительную проверку, что список не пуст:

boolean validate = !serviceWorkList.isEmpty() && serviceWorkList
    .stream()
    .filter(ServiceWork::isRequirement)
    .allMatch(a -> a.getStatus() == Status.DONE);

После вашего комментария вы можете использовать это:

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();

Сначала он собирает все состояния в EnumSet, затем удаляет Status.DONE из набора, и если набор пуст, каждый элемент имеет getStatus() == Status.DONE.

Это устраняет короткое замыкание, поэтому оно все еще будет повторяться по serviceWorkerList, хотя Status, отличное от Status.DONE, было обнаружено

1 голос
/ 15 марта 2019

Stream.allMatch () всегда будет возвращать true для пустого списка

Вы должны добавить другую проверку, например

boolean validate = !serviceWorkList.isEmpty() && serviceWorkList
    .stream()
    .filter(ServiceWork::isRequirement)
    .allMatch(a -> a.getStatus() == Status.DONE);
0 голосов
/ 15 марта 2019

Будет нецелесообразно проводить полную проверку в одной потоковой операции.Я предлагаю две потоковые операции:

    boolean allRequirementsDone = serviceWorkList.stream()
            .filter(ServiceWork::isRequirement)
            .allMatch(a -> a.getStatus() == Status.DONE);
    boolean atLeastOneRequirement = serviceWorkList.stream()
            .anyMatch(ServiceWork::isRequirement);
    boolean validate = allRequirementsDone && atLeastOneRequirement;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...