【问题标题】:Better way to create a stream of functions?创建函数流的更好方法?
【发布时间】:2017-12-17 08:29:31
【问题描述】:

我希望对我定义如下的函数列表进行惰性求值;

Optional<Output> output = Stream.<Function<Input, Optional<Output>>> of(
                    classA::eval, classB::eval, classC::eval)
            .map(f -> f.apply(input))
            .filter(Optional::isPresent)
            .map(Optional::get)
            .findFirst();

如您所见,每个类(a、b 和 c)都定义了一个 Optional&lt;Output&gt; eval(Input in) 方法。如果我尝试做

Stream.of(...)....

忽略显式类型,它给出

T 不是函数式接口

编译错误。不接受 .of(T... values)T 泛型类型的功能接口类型@


有没有更快捷的方法来创建这些函数的流?我讨厌用Function 及其输入输出类型明确定义of 方法。它不会以更通用的方式工作吗?

这个问题源于下一个问题的主题;
Lambda Expression and generic method

【问题讨论】:

  • 可以分享签名ClassA#eval吗?
  • 问题中已经存在Optional&lt;Output&gt; eval(Input in),所有ClassAClassBClassC 都相同
  • 阅读时跳过了那一行,过失。
  • @Mureinik :) 人为错误
  • 注意:您现在可以使用.flatMap(Optional::stream) 代替isPresent get 成语。

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


【解决方案1】:

你可以把它分成两行:

Stream<Function<Input, Optional<Output>>> stream = Stream
          .of(classA::eval, classB::eval, classC::eval);
Optional<Output> out = stream.map(f -> f.apply(input))
          .filter(Optional::isPresent)
          .map(Optional::get)
          .findFirst();

或使用强制转换:

Optional<Output> out = Stream.of(
                (<Function<Input, Optional<Output>>>)classA::eval, 
                classB::eval, 
                classC::eval)
        .map(f -> f.apply(input))
        .filter(Optional::isPresent)
        .map(Optional::get)
        .findFirst();

但我认为您无法避免在某处指定 Stream 元素的类型 - Function&lt;Input, Optional&lt;Output&gt;&gt; - 因为否则编译器无法从方法引用中推断出它。

【讨论】:

    【解决方案2】:

    有一种方法可以省略Function&lt;Input, Optional&lt;Output&gt;&gt; 类型,但不一定是改进

    Optional<Output> o =
            Stream.concat(Stream.of(input).map(classA::eval),
                    Stream.concat(Stream.of(input).map(classB::eval),
                                  Stream.of(input).map(classC::eval)))
                    .filter(Optional::isPresent)
                    .map(Optional::get)
                    .findFirst();
    

    而且它无法扩展。

    看来,最好的选择是等待可以使用的Java-9

    Optional<Output> o = classA.eval(input)
               .or(() -> classB.eval(input))
               .or(() -> classC.eval(input));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-23
      相关资源
      最近更新 更多