使用 Lambdas 合并对象和列表
Merging Object and List with Lambdas
我遇到的情况类似如下:
List<ObjectA> all = repository.findAll(Sort.by(Sort.Direction.ASC, "status"));
这将找到具有三种可能状态的对象列表:OPEN、CLOSED、PROGRAMMED
现在我必须 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.of
、Stream.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();
我遇到的情况类似如下:
List<ObjectA> all = repository.findAll(Sort.by(Sort.Direction.ASC, "status"));
这将找到具有三种可能状态的对象列表:OPEN、CLOSED、PROGRAMMED
现在我必须 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.of
、Stream.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
对象不存在,您决定 returnnull
。但是如果没有open
对象,方法get()
将引发NoSuchElementException
.
ObjectA programmed = all.stream().filter(isPROGRAMMED()).reduce((x,y) -> y).orElse(null);
ObjectA open = all.stream().filter(isOPEN()).findFirst().get();