java - 在 Java 流之间共享/重用公共操作序列的最佳方式
问题描述
如果我在两个流中有一个共同的操作序列,如何共享它们以避免重复代码?到目前为止,我发现我可以使用:
Stream<U> commonSequence(Stream<T> upstream) {
return upstream.op1().op2().op3()
}
然后将其用作
commonSequence(upStream()).downStream()
但是事情并没有真正按照它们发生的顺序来写。我是否忽略了一些可以让我编写如下内容的技巧:
upStream().wrap(commonPart).downStream()
解决方案
您可以自己制作Collector
,但效率可能不高。
下面的收集器有点等价于做filter("foo").limit(10)
.
class FilterFooAndLimit10Collector<T> implements Collector<T, List<T>, Stream<T>> {
@Override
public Supplier<List<T>> supplier() {
return () -> new ArrayList<>();
}
@Override
public BiConsumer<List<T>, T> accumulator() {
return (list, elem) -> {
if (!"foo".equals(elem)) list.add(elem);
};
}
@Override
public BinaryOperator<List<T>> combiner() {
return (list1, list2) -> {
var res = new ArrayList<T>(list1.size() + list2.size());
res.addAll(list1);
res.addAll(list2);
return res;
};
}
@Override
public Function<List<T>, Stream<T>> finisher() {
return list -> list.stream().limit(10);
}
@Override
public Set<Collector.Characteristics> characteristics() {
return new HashSet<>();
}
}
你可以像这样使用它:
Stream
.of("foo", "bar", "baz", "foo", "quux", "corge", "fred", "waldo", "spam", "ham", "eggs", "foo", "foobar", "xyzzy")
.collect(new FilterFooAndLimit10Collector<String>())
.forEach(x -> System.out.println(x));
这将产生输出
bar
baz
quux
corge
fred
waldo
spam
ham
eggs
foobar
当然,您可以修改它以采用构造函数参数以获得更广泛的行为,或者使用其他一些数据结构对其进行优化,但我个人更喜欢commonSequence(stream)
.
推荐阅读
- elasticsearch - 使用 NEST 设置 Elasticsearch routing_partition_size
- elasticsearch - 仅来自唯一值的 Date_histogram 和 top_hits
- graphql - 使用 Apollo Server 运行 Jest 失败 global.fetch undefined
- java - 反转屏幕,包括 null 和空字符串
- java - 使用自定义容器作为数据库与 TestContainer
- c++ - qtconcurrent 没有用于调用“运行”的匹配函数
- html - 为什么使用 grid-template-areas 与同一类的网格区域但不同的选择器以相反的顺序显示?
- r - 调整条形图 y 轴,以便可以很好地绘制更高的 y 值
- amazon-web-services - AWS MSK 引导服务器名称是否与公共 DNS 服务器解析
- python - 如何读取 .txt 文件,并在特定位置/索引后添加空格,为 python 中的每一行