将助焊剂分成两个助焊剂 - 头部和尾部

Posted

技术标签:

【中文标题】将助焊剂分成两个助焊剂 - 头部和尾部【英文标题】:Split a flux into two fluxes - head and tail 【发布时间】:2020-02-29 23:20:24 【问题描述】:

我想将通量分成两个通量,其中第一个具有原始通量的第一项,第二个将获取其余项。

在对每个通量应用自定义转换 myLogic 后,我想将它们组合成一个通量,保留原始通量的顺序。

例子:

S:学生 S':申请后的学生myLogic

发射通量:s1 -> s2 -> s3 -> s4 第一个分裂通量:s1' => myLogic 第二次分裂通量:s2' -> s3' -> s4' => myLogic 合流:s1' -> s2' -> s3' -> s4'

【问题讨论】:

也许你只需要一个LinkedList @suliman 请接受您认为对该问题最有帮助的答案。 【参考方案1】:

使用标准的Flux 方法takeskip 来分离头部和尾部元素就足够了。在此之前调用cache 也有助于避免重复订阅。

class Util 

  static <T, V> Flux<V> dualTransform(
    Flux<T> originalFlux,
    int cutpointIndex,
    Function<T, V> transformHead,
    Function<T, V> transformTail
  ) 
    var cached = originalFlux.cache();
    var head = cached.take(cutpointIndex).map(transformHead);
    var tail = cached.skip(cutpointIndex).map(transformTail);

    return Flux.concat(head, tail);
  

  static void test() 
    var sample = Flux.just("a", "b", "c", "d");

    var result = dualTransform(
                   sample,
                   1, 
                   x -> "" + x.toUpperCase() + "", 
                   x -> "(" + x + ")"
                 );

    result.doOnNext(System.out::print).subscribe();

    // prints: A(b)(c)(d)
  

【讨论】:

【参考方案2】:

您的问题有一个更简单的解决方案。您不需要拆分和合并来自发布者的事件。您可以使用index()。它保存有关事件发布顺序的信息。

Flux<String> values = Flux.just("s1", "s2", "s3");
values.index((i, v) -> 
  if (i == 0) 
    return v.toUpperCase();
   else 
    return v.toLowerCase();
  
);

【讨论】:

【参考方案3】:

这里有一个 hacky 方法来做到这一点:

boolean a[] = new boolean[]false;  //use an array as you cannot use non-final variables inside lambdas

    originalFlux
        .flatMap(a -> 
            if(!a[0]) 
                a[0] = true;
                return runLogicForFirst(a);
             else 
                return runLogicForRest(a);
            
        )

【讨论】:

【参考方案4】:

无需创建两个单独的 Flux 对象然后合并它们,您只需将原始 Flux 与另一个 Flux&lt;Boolean&gt; 压缩,后者仅在第一个元素上使用 true

然后,您可以在正常的map() 电话中随意进行有条件的处理,而无需稍后合并单独的发布者:

Flux<String> values = Flux.just("A", "B", "C", "D", "E", "F", "G");

Flux.zip(Flux.concat(Flux.just(true), Flux.just(false).repeat()), values)
        .map(x -> x.getT1() ? "_"+x.getT2().toUpperCase()+"_" : x.getT2().toLowerCase())
        .subscribe(System.out::print);    // prints "_A_bcdefg"

【讨论】:

以上是关于将助焊剂分成两个助焊剂 - 头部和尾部的主要内容,如果未能解决你的问题,请参考以下文章

java合并两个通量没有重复

使用助焊剂时的表单验证

如何使用弹簧反应 webflux 中的单声道和助焊剂使用 DTO 制作新的单声道

助焊剂 TCA db 组

如何使用助焊剂商店

Flux/Alt 数据依赖,如何优雅地道地处理