Enum实现lambda可能接口的简写表示法

时间:2016-03-02 15:04:07

标签: java lambda enums java-8 enumeration

来自jparsec的Java 8前例子,我想知道我是否可以利用lambdas来表达更具表现力的语法。

原始示例:

?   text    Does the string exist as a top-level key within the JSON value?

,其中

enum BinaryOperator implements Map2<Double,Double,Double> {
  PLUS {
    public Double map(Double a, Double b) {
      return a + b;
    }
  },
  MINUS {
    public Double map(Double a, Double b) {
      return a - b;
    }
  },
  MUL {
    public Double map(Double a, Double b) {
      return a * b;
    }
  },
  DIV {
    public Double map(Double a, Double b) {
      return a / b;
    }
  }
}

使用例如,可以轻松创建普通的Map2实例。 public interface Map2<A, B, T> { /** Maps {@code a} and {@code b} to the target object. */ T map(A a, B b); } ,但有一种简洁的方法可以为实现单一功能界面的枚举做同样的事情吗?

我目前的解决方案看起来像这样,但它仍然是冗长的:

(a,b)->a+b

2 个答案:

答案 0 :(得分:7)

此处适当的界面为DoubleBinaryOperator。当您需要操作两个double值并返回double时,此界面非常适合。它适用于原始double而不是包装类,因此它没有装箱开销。

您当前的解决方案仍然是可行的方法。代码是明确的因素,并没有重复。使用上面的界面,您可以:

enum BinaryOperator implements DoubleBinaryOperator {
    PLUS((a, b) -> a + b),
    MINUS((a, b) -> a - b),
    MUL((a, b) -> a * b),
    DIV((a, b) -> a / b);

    private final DoubleBinaryOperator f;

    private BinaryOperator(DoubleBinaryOperator f) {
        this.f = f;
    }

    @Override
    public double applyAsDouble(double a, double b) {
        return f.applyAsDouble(a, b);
    }

}

实现DoubleBinaryOperator接口可以证明是有用的:这样你可以直接将枚举值用作DoubleBinaryOperator,如:

DoubleStream.of(1, 2, 3).reduce(0, BinaryOperator.PLUS);

(这只是一个例子;有更好的方法来完成这个特定的实例。)

答案 1 :(得分:1)

恕我直言,更简洁的是使用EnumMap将每个Operation值映射到相应的操作:

enum Operator { PLUS, MINUS, MUL, DIV; }

然后,您需要初始化EnumMap

EnumMap<Operator, DoubleBinaryOperator> operations = new EnumMap<>(Operator.class);
operations.put(Operator.PLUS, (a, b) -> a + b);
operations.put(Operator.MINUS, (a, b) -> a - b);
operations.put(Operator.MUL, (a, b) -> a * b);
operations.put(Operator.DIV, (a, b) -> a / b);

用法示例:

double result = operations.get(Operator.MUL).applyAsDouble(2.0, 3.0); // 6.0

编辑:正如@Holger在评论中建议的那样,检查您是否已将所有可能的枚举值添加到地图中会很高兴。这可以通过assert

来完成
assert operations.keySet().equals(EnumSet.allOf(Operator.class));