【问题标题】:How to exclude all elements in Flux from another Flux如何从另一个 Flux 中排除 Flux 中的所有元素
【发布时间】:2020-02-24 15:27:53
【问题描述】:

我有两个Fluxs 一个用于成功元素,另一个用于保存错误元素

Flux<String> success= Flux.just("Orange", "Apple", "Banana","Grape", "Strawberry");
Flux<String> erroneous = Flux.just("Banana","Grape",);

如何过滤第一个 Flux 以排除第二个中的所有元素?

【问题讨论】:

    标签: java spring stream project-reactor


    【解决方案1】:

    您不妨考虑将Flux 收集到一个集合中,缓存该集合,然后使用filterWhen,如下所示:

    Mono<Set<String>> erroneousSet = erroneous.collect(Collectors.toSet()).cache();
    Flux<String> filtered = success.filterWhen(v -> erroneousSet.map(s -> !s.contains(v)));
    

    给予:

    Orange
    Apple
    Strawberry
    

    这不是最简洁的解决方案(见下文),但它可以缓存erroneous 的内容。在这个具体的例子中,这是一个有争议的问题,但如果它是真实世界的情况(不使用Flux.just()),那么erroneous 可以在每次订阅时重新计算,这最终可能会在性能方面变得难以置信(并且不必要地)昂贵.

    或者,如果上述内容在您的用例中确实无关紧要,filterWhen()hasElement() 可以更简洁地使用如下:

    success.filterWhen(s -> erroneous.hasElement(s).map(x->!x))
    

    或者使用 reactor-extra:

    success.filterWhen(s -> BooleanUtils.not(erroneous.hasElement(s)))
    

    【讨论】:

    • 一个字,完美
    • 理想情况下会有一个hasNoElement() 或类似的来避免最终的map() 调用,但这是目前最好的解决方法:-)
    • @MeladBasilius 如果您碰巧已经有reactor-extra,那么您只需脑电波并使用稍微不同的替代方案进行更新。不过,仅仅为此包括它并没有多大意义。
    • 请注意,如果您有机会首先收集要在set 中排除的元素并改用.filter(...),则为此目的使用Flux 可能有点不适应。特别是如果erroneous 每次订阅时都会重新计算,而just 仅用于演示目的
    • @SimonBaslé 这是一个很好的观点。我猜如果Flux 是唯一可用的源(假设它终止),那么更好的选择可能是作为集合收集和缓存,即erroneousSet = erroneous.collect(Collectors.toSet()).cache()success.filterWhen(v -&gt; erroneousSet.map(s -&gt; !s.contains(v))) - 这有意义还是有更简洁的我错过了什么?
    猜你喜欢
    • 2020-01-04
    • 2021-08-05
    • 2021-03-21
    • 2020-07-30
    • 2018-12-08
    • 1970-01-01
    • 2018-09-15
    • 2019-12-17
    • 1970-01-01
    相关资源
    最近更新 更多