【发布时间】:2014-04-29 09:59:12
【问题描述】:
你们中的许多人可能都知道,Operation 枚举有一个经典示例(不过现在使用 Java 8 标准接口),如下所示:
enum Operation implements DoubleBinaryOperator {
PLUS("+") {
@Override
public double applyAsDouble(final double left, final double right) {
return left + right;
}
},
MINUS("-") {
@Override
public double applyAsDouble(final double left, final double right) {
return left - right;
}
},
MULTIPLY("*") {
@Override
public double applyAsDouble(final double left, final double right) {
return left * right;
}
},
DIVIDE("/") {
@Override
public double applyAsDouble(final double left, final double right) {
return left / right;
}
};
private final String symbol;
private Operation(final String symbol) {
this.symbol = symbol;
}
public String getSymbol() {
return symbol;
}
}
测试:
Arrays.stream(Operation.values())
.forEach(op -> System.out.println("Performing operation " + op.getSymbol() + " on 2 and 4: " + op.applyAsDouble(2, 4)));
它提供:
在 2 和 4 上执行 + 操作:6.0
执行操作 - 在 2 和 4:-2.0
在 2 和 4 上执行操作 *:8.0
在 2 和 4 上执行操作 /:0.5
但我觉得我们可以使用 Java 8 做得更好,因此我实现了以下内容:
enum Operation implements DoubleBinaryOperator {
PLUS ("+", (l, r) -> l + r),
MINUS ("-", (l, r) -> l - r),
MULTIPLY("*", (l, r) -> l * r),
DIVIDE ("/", (l, r) -> l / r);
private final String symbol;
private final DoubleBinaryOperator binaryOperator;
private Operation(final String symbol, final DoubleBinaryOperator binaryOperator) {
this.symbol = symbol;
this.binaryOperator = binaryOperator;
}
public String getSymbol() {
return symbol;
}
@Override
public double applyAsDouble(final double left, final double right) {
return binaryOperator.applyAsDouble(left, right);
}
}
在功能上是等价的,但是两个实现是否仍然相似,或者是否有一些隐藏的细节使新版本比旧版本更糟?
最后,从 Java 8 开始,lambda 方式是首选方式吗?
【问题讨论】:
-
Effective Java,第 3 版现在推荐使用这个例子的 lambda 方法。
-
问题:这里使用枚举是否比具有常量的简单公共类(或内部公共类)有任何好处?即
public static final DoubleBinaryOperator PLUS = (l, r) -> l + r;? -
@Andrejs 他们有名字并且可以有额外的属性,比如
symbol,它允许创建地图。当您免费获得“迭代所有常量”逻辑时,这很顺利。 -
基本上这是一个正确的application of the strategy pattern。