使用 Lambdas 合并对象和列表

Merging Object and List with Lambdas

我遇到的情况类似如下:

List<ObjectA> all = repository.findAll(Sort.by(Sort.Direction.ASC, "status"));

这将找到具有三种可能状态的对象列表:OPENCLOSEDPROGRAMMED

现在我必须 return 一个向用户显示最后一个 PROGRAMMED 对象、第一个 OPEN 对象和所有关闭对象的列表。我写了类似的东西:

ObjectA programmed = all.stream().filter(isPROGRAMMED()).reduce((x,y) -> y).orElse(null);
ObjectA open = all.stream().filter(isOPEN()).findFirst().get();
List<ObjectA> closed = all.stream().filter(isCLOSED()).collect(Collectors.toList());

isOPEN()isPROGRAMMED()isCLOSED()是Predicate我写的如下:

private static Predicate<ObjectA> isPROGRAMMED() {
    return x -> x.getStatus().equals(Stato.PROGRAMMED);
}

private static Predicate<ObjectA> isOPEN() {
    return x -> x.getStatus().equals(Stato.OPEN);
}

private static Predicate<ObjectA> isCLOSED() {
    return x -> x.getStatus().equals(Stato.CLOSED);
}

现在我只想将两个对象和第三个列表合并为一个。列表应包含已编程的项目(如果存在)打开的对象(如果存在),然后是所有关闭的项目。我用 Stream.ofStream.concat 尝试过,但我总是遇到一些编译错误..

有没有什么方法可以用 Lambdas 和很少的代码来做到这一点?

如果您想避免 closed 列表的突变,那么 Stream IPA 是此任务的可能选择之一。

可以这样做:

    public static List<ObjectA> merge(List<ObjectA> closed, ObjectA programmed, ObjectA open) {
        return Stream.concat(Stream.of(programmed, open), 
                             closed.stream())
                .collect(Collectors.toList());
    }

正如我在评论中已经提到的,如果不关心保留 closed 列表的初始状态,则可以将这些对象直接添加到列表中。由于在列表的开头添加一个新元素的成本很高(如果它由数组支持),更好的选择是使用 addAll() 并按照 Holger 的建议在一次操作中添加两个值:

        closed.addAll(0, Arrays.asList(programmed, open));

旁注:

  • 您获取 programmed 对象和 open 对象的方式不一致。如果 programmed 对象不存在,您决定 return null。但是如果没有 open 对象,方法 get() 将引发 NoSuchElementException.
ObjectA programmed = all.stream().filter(isPROGRAMMED()).reduce((x,y) -> y).orElse(null);
ObjectA open = all.stream().filter(isOPEN()).findFirst().get();