Насколько я понимаю, вам нужен метод, аналогичный DefaultIfEmpty в C #.К сожалению, в Stream API такого метода нет, но, к счастью, кто-то уже реализовал что-то подобное.
Используя метод defaultIfEmpty
из @ Stuart Marks answer , пример использования довольно прост.
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);
На этом этапе вы, вероятно,Осознайте, что читаемость теряется, и это останется таковым, когда вы будете выполнять дальнейшие операции.
Тем не менее, это наилучший из возможных способов, так как я не могу придумать какой-либо другой способ добиться этого, поддерживая хорошую читаемость, поскольку вы создаете все больше и больше методов в потоке.