首页 > 解决方案 > 在 Java 中将 BiFunction 转换为函数

问题描述

假设我有以下枚举:

public enum Foo {

  AAA(new A()::doA),
  BBB(new B()::doB),
  CCC(new C()::doC),
  DDD(new D()::doD);

  private Function<String, Number> do;

  Foo(Function<String, Number> do) {
    this.do = do;
  }

  public Function<String, Number> getDo() {
    return do;
  }  
}

知道我必须保持getDo方法具有完全相同的签名。

这工作正常,如果我这样做AAA.getDo().apply("two"),我会得到2结果。但问题是对do方法的每次调用总是在 A、B、C 和 D 的相同实例上完成。但是,我需要 A、B、C 或 D 在每次调用时都是不同的实例(因为这些类有字段,我不希望这些字段在每次调用do方法时都保持它们的值)。

我想过这样的事情:

AAA(
  A.class,
  A::doA);

但是在这种情况下A::doA,不再是 A 实例上的 Function ,而是我需要将 A 的实例作为第一个参数传递给的 BiFunction 。但是我的getDo方法仍然必须返回一个函数,而且我看不到任何方法可以将我的 BiFunction 和我的 A 类转换为 A 实例上的函数(我们可以想象类似 : (A::DoA).toFunction(A.class))。

标签: javalambdajava-8

解决方案


方法引用new A()::doA绑定到在评估创建实例A时创建的一个对象,即创建枚举值时。立即执行并返回对其方法的引用,就像您使用过.new A()::doAFunctionAAAnew A()doA()someInstanceOfA::doA

修复它的方法是让函数本身在不立即运行的逻辑中调用构造函数:

AAA(s -> new A().doA(s)), 
BBB(s -> new B().doB(s)), 
CCC(s -> new C().doC(s)), 
DDD(s -> new D().doD(s));

推荐阅读