如果使用Stream.allMatch(),如何为空列表返回false?

时间:2019-03-15 11:43:18

标签: java java-stream

我想对Java流使用一条语句。

我要过滤所有要求为“ true”的Servicework对象,然后检查所有Servicework对象的状态是否为“ Done”。

但是,如果serviceworkList列表为空,则变量“ validate”为false。 我知道allMatch的规范,即如果list为空,则返回true。

关于如何重新构建流的任何建议,如果list ist为空,我会得到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 个答案:

答案 0 :(得分:8)

只需添加其他检查,以确保列表不为空:

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 :(得分:1)

Stream.allMatch()对于空列表始终返回true

您应该添加其他验证,例如

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

答案 2 :(得分:0)

在一个流操作中进行整个验证是不切实际的。我建议执行两个流操作:

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