据我了解,您需要一个类似于 C# 中的DefaultIfEmpty 的方法。不幸的是,Stream API 没有这种方法,但幸运的是,有人已经实现了这种方法。
采用@Stuart Marks answer中的defaultIfEmpty方法,用例非常简单。
static <T> Stream<T> defaultIfEmpty(Stream<T> stream, Supplier<T> supplier) {
Iterator<T> iterator = stream.iterator();
if (iterator.hasNext()) {
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false);
} else {
return Stream.of(supplier.get());
}
}
例如,假设您有一个整数列表:
List<Integer> integerList = new ArrayList<>(Arrays.asList(1,3,5,7,9));
如果上述列表中没有偶数,您想要一个具有单个值的流。
用例是:
Stream<Integer> result = defaultIfEmpty(integerList.stream()
.filter(e -> e %2 == 0), () -> 99);
这将产生一个Stream<Integer>,其中单个元素为99,因为filter 操作返回了一个空流。然后,您可以在从defaultIfEmpty 返回的流上链接进一步的操作,即
defaultIfEmpty(integerList.stream()
.filter(e -> e %2 == 0), () -> 99)
.map(x -> x*2)
...
...
或将后续的defaultIfEmpty 方法应用于:
Stream<Integer> result = defaultIfEmpty(
defaultIfEmpty(integerList.stream()
.filter(e -> e %2 == 0),
() -> 99).map(x -> x* 2)..., ()-> -1);
此时,您可能会意识到可读性正在丧失,并且在您编写进一步的操作时仍会如此。
尽管如此,这是最好的方法,因为我想不出任何其他方法来实现这一点,同时在流中编写越来越多的方法时保持良好的可读性。