将助焊剂分成两个助焊剂 - 头部和尾部
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
方法take
和skip
来分离头部和尾部元素就足够了。在此之前调用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<Boolean>
压缩,后者仅在第一个元素上使用 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"
【讨论】:
以上是关于将助焊剂分成两个助焊剂 - 头部和尾部的主要内容,如果未能解决你的问题,请参考以下文章