【问题标题】:Best way to share/re-use a common sequence of operations between Java streams在 Java 流之间共享/重用公共操作序列的最佳方式
【发布时间】:2021-03-05 00:02:59
【问题描述】:

如果我在两个流中有一个共同的操作序列,如何共享它们以避免重复代码?到目前为止,我发现我可以使用:

Stream<U> commonSequence(Stream<T> upstream) {
    return upstream.op1().op2().op3()
}

然后把它当作

commonSequence(upStream()).downStream()

但是事情并没有真正按照它们发生的顺序来写。我是否忽略了一些可以让我编写如下内容的技巧:

upStream().wrap(commonPart).downStream()

【问题讨论】:

  • 你检查过这个答案吗:stackoverflow.com/questions/24474838/… 它似乎解决了一个类似(如果不一样)的问题?
  • 我不认为这是相同的:这是对同一个流执行两个不同的操作,而 OP 想对多个流执行相同的操作。
  • 你能说得更具体一点吗?操作?
  • 但是我不会再担心“按照它们发生的顺序”写东西,我们习惯于将参数值视为在应用它们传递给的函数之前计算的东西。
  • 对您来说可能不是一个实用的选择,但 Groovy 和 Kotlin 支持 扩展方法 正是这种用例。

标签: java java-stream


【解决方案1】:

您可以创建自己的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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-11
    • 2011-11-06
    • 2016-11-15
    • 1970-01-01
    • 1970-01-01
    • 2017-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多