该Stream.flatMap()操作转换了一个流
a, b, c
Run Code Online (Sandbox Code Playgroud)
进入包含每个输入元素的零个或多个元素的流,例如
a1, a2, c1, c2, c3
Run Code Online (Sandbox Code Playgroud)
是否有相反的操作将一些元素分成一个新元素?
void并且与副作用一起使用它存在吗?我可以用任何方式模拟它吗?
最后我发现这flatMap就是它自己的“逆”。我发现这flatMap不一定会增加元素的数量。它还可以通过为某些元素发出空流来减少元素的数量。为了实现 group-by 操作,by 调用的函数flatMap需要最小的内部状态,即最新的元素。它要么返回一个空流,要么在组的末尾返回简化为组的代表。
这是一个快速实现,如果传入的两个元素不属于同一组(即它们之间是组边界),则groupBorder必须返回。true假设您的组元素是combiner元组 (int, string),则该组函数会将 (1,a)、(1,a)、(1,a) 组合为 (3,a)。
public class GroupBy<X> implements Function<X, Stream<X>>{
private final BiPredicate<X, X> groupBorder;
private final BinaryOperator<X> combiner;
private X latest = null;
public GroupBy(BiPredicate <X, X> groupBorder,
BinaryOperator<X> combiner) {
this.groupBorder = groupBorder;
this.combiner = combiner;
}
@Override
public Stream<X> apply(X elem) {
// TODO: add test on end marker as additonal parameter for constructor
if (elem==null) {
return latest==null ? Stream.empty() : Stream.of(latest);
}
if (latest==null) {
latest = elem;
return Stream.empty();
}
if (groupBorder.test(latest, elem)) {
Stream<X> result = Stream.of(latest);
latest = elem;
return result;
}
latest = combiner.apply(latest, elem);
return Stream.empty();
}
}
Run Code Online (Sandbox Code Playgroud)
但有一个警告:要发送整个流的最后一组,必须将结束标记作为最后一个元素粘贴到流中。上面的代码假设它是null,但是可以添加一个额外的结束标记测试器。
我无法想出一个不依赖结束标记的解决方案。
此外,我也没有在传入和传出元素之间进行转换。对于一个独特的操作,这会起作用。对于计数操作,前面的步骤必须将各个元素映射到计数对象。