繁体   English   中英

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

[英]Shorthand notation for Enum implementing lambda possible interface

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

原始示例:

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;
    }
  }
}

哪里

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可以轻松创建普通的Map2实例,但对于实现单个函数接口的枚举,是否有简洁的方法来执行相同的操作?

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

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

    private final BiFunction<Double, Double, Double> f;

    private BinaryOperator(BiFunction<Double, Double, Double> f) {
        this.f = f;
    }

    @Override
    public Double map(Double a, Double b) {
        return f.apply(a, b);
    }
}

这里适当的接口是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);

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

恕我直言,更简洁的是使用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));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM