在Java8中将映射器流应用于另一个流

sla*_*dan 5 java functional-programming java-8 java-stream

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

例如:

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

我想写:

strings.map(mappers); // not working
Run Code Online (Sandbox Code Playgroud)

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

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

strings.forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)

我怎么解决这个问题

  • 没有将映射器收集到列表中
  • 不使用for循环
  • 没有打破我的流利代码

Hol*_*ger 8

由于map需要一个可以应用于每个元素的函数,但是您Stream<Function<…>>只能进行一次评估,因此将流处理为可重用的东西是不可避免的.如果它不应该是a Collection,只需将其减少为单个Function:

strings.map(mappers.reduce(Function::andThen).orElse(Function.identity()))
Run Code Online (Sandbox Code Playgroud)

完整的例子:

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);
Run Code Online (Sandbox Code Playgroud)

  • @rgettman:`orElse`变体是一个小优化,因为它没有将身份函数与另一个函数结合起来. (3认同)