4 回答

TA貢獻(xiàn)1853條經(jīng)驗 獲得超9個贊
您可以創(chuàng)建自定義Collector
(此處稱為StreamInterceptor
),即使這并不真正符合收藏家的目的。
自定義收集器將做什么?
轉(zhuǎn)換
Stream<T>
為List<T>
調(diào)用 Consumer<List>,在您的情況下它將打印列表的長度。
返回一個新
Stream<T>
的List<T>
主要方法
在這里,我剛剛將您的問題分解為過濾一個簡單的字符串列表,并在最后將它們打印到控制臺。
public static void main(String[] args) {
List<String> myList = List.of("first", "second", "third");
myList.stream()
.filter(string -> !string.equals("second"))
.collect(printCount())
.forEach(System.out::println);
}
/**
* Creates a StreamInterceptor, which will print the length of the stream
*/
private static <T> StreamInterceptor<T> printCount() {
Consumer<List<T>> listSizePrinter = list -> System.out.println("Stream has " + list.size() + " elements");
return new StreamInterceptor<>(listSizePrinter);
}
初始化時,StreamInterceptor您可以定義一個消費者,它接收從流構(gòu)造的中間列表并對其執(zhí)行一些操作。在您的情況下,它只會打印列表的大小。
新StreamInterceptor班級
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.function.*;
import java.util.stream.Collector;
import java.util.stream.Stream;
class StreamInterceptor<T> implements Collector<T, List<T>, Stream<T>> {
private final Consumer<List<T>> listConsumer;
public StreamInterceptor(Consumer<List<T>> listConsumer) {
this.listConsumer = listConsumer;
}
@Override
public Supplier<List<T>> supplier() {
return ArrayList::new;
}
@Override
public BiConsumer<List<T>, T> accumulator() {
return List::add;
}
@Override
public BinaryOperator<List<T>> combiner() {
return (list1, list2) -> {
list1.addAll(list2);
return list1;
};
}
@Override
public Function<List<T>, Stream<T>> finisher() {
return list -> {
listConsumer.accept(list);
return list.stream();
};
}
@Override
public Set<Characteristics> characteristics() {
return Collections.emptySet();
}
}

TA貢獻(xiàn)1844條經(jīng)驗 獲得超8個贊
您可以peek在將列表轉(zhuǎn)換為stream.
public static void main(String[] args) {
Stream.of(Arrays.asList(1, 2, 3), Arrays.asList(4, 5), Collections.emptyList())
.filter(x -> x.size() % 2 == 0)
.peek(s -> System.out.println(s.isEmpty()))
.flatMap(Collection::stream)
.forEach(System.out::println);
}
輸出
false
4
5
true

TA貢獻(xiàn)1790條經(jīng)驗 獲得超9個贊
這根本不是真正的“好”,但您可以使用 peek 查看您的流并設(shè)置一個 AtomicBoolean:
AtomicBoolean empty = new AtomicBoolean(true);
scheduleService.list().stream()
.filter(Schedule::getEnabled)
.filter(this::runnable)
.flatMap(s -> s.getJobs().stream())
.peek(s -> ab.set(false);)
.forEach(this::invoke);
if(empty.get()){
// is Empty
}

TA貢獻(xiàn)1784條經(jīng)驗 獲得超9個贊
您可以將您包裝Stream成如下所示的自定義方法
Stream<???> stream = scheduleService.list().stream()
.filter(Schedule::getEnabled)
.filter(this::runnable)
.flatMap(s -> s.getJobs().stream());
forEachOrElse(stream, this::invoke, () -> System.out.println("The stream was empty"));
隨著forEachOrElse存在
public <T> void forEachOrElse(Stream<T> inStream, Consumer<T> consumer, Runnable orElse) {
AtomicBoolean wasEmpty = new AtomicBoolean(true);
inStream.forEach(e -> {
wasEmpty.set(false);
consumer.accept(e);
});
if (wasEmpty.get())
orElse.run();
}
我現(xiàn)在無法測試它,但它應(yīng)該會發(fā)揮它的魔力
添加回答
舉報