【问题标题】:Apply a stream of mappers to another stream in Java8将映射器流应用于Java8中的另一个流
【发布时间】:2015-11-03 19:15:48
【问题描述】:

在 Java8 中,我有一个流,我想应用一个 映射器流

例如:

Stream<String> strings = Stream.of("hello", "world");
Stream<Function<String, String>> mappers = Stream.of(t -> t+"?", t -> t+"!", t -> t+"?");

我想写:

strings.map(mappers); // not working

但我目前解决任务的最佳方式是:

for (Function<String, String> mapper : mappers.collect(Collectors.toList()))
    strings = strings.map(mapper);

strings.forEach(System.out::println);

我该如何解决这个问题

  • 不将映射器收集到列表中
  • 不使用for 循环
  • 不破坏我流畅的代码

【问题讨论】:

    标签: java functional-programming java-8 java-stream


    【解决方案1】:

    由于map 需要一个可以应用于每个元素的函数,但您的Stream&lt;Function&lt;…&gt;&gt; 只能评估一次,因此不可避免地将流处理为可重用的东西。如果不应该是Collection,只需将其缩减为单个Function

    strings.map(mappers.reduce(Function::andThen).orElse(Function.identity()))
    

    完整示例:

    Stream<Function<String, String>> mappers = Stream.of(t -> t+"?", t -> t+"!", t -> t+"?");
    Stream.of("hello", "world")
          .map(mappers.reduce(Function::andThen).orElse(Function.identity()))
          .forEach(System.out::println);
    

    【讨论】:

    • 其他有效的变体:mappers.reduce(Function.identity(), Function::andThen)mappers.reduce(Function.identity(), Function::compose)
    • @rgettman:orElse 变体是一个小的优化,因为它没有将身份函数与另一个函数结合起来。
    • 如果Function.identity() 覆盖composeandThen 就好了……或者JIT 编译器无论如何都会摆脱这种复杂性?
    • @Didier L:这样的覆盖会很好,但它不能再实现为简单的 lambda 表达式 t-&gt;t。当涉及 CPU 复杂性时,如果函数成为热点,JIT确实优化掉这些东西。然后,只剩下一小部分额外的内存分配(除非逃逸分析可以证明这是纯粹的本地事情)。这就是为什么我说,这是一个优化。
    猜你喜欢
    • 2018-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-17
    相关资源
    最近更新 更多