'Why can't the instance member be accessed from the lambda of the enum constructor?
In the code below, I am trying to output the value of a symbol that is an instance variable of Operation from a PLUS constant.
But I can't access that variable.
What's the problem?
public enum Operation {
PLUS("+", (x, y) -> {
System.out.println(symbol);
return x + y;
}),
MINUS("-", (x, y) -> x - y),
TIMES("*", (x, y) -> x * y),
DIVIDE("/", (x, y) -> x / y);
Operation(String symbol, DoubleBinaryOperator op) {
this.symbol = symbol;
this.op = op;
}
public String getSymbol() {
return symbol;
}
protected final String symbol;
private final DoubleBinaryOperator op;
public double apply(double x, double y) {
return op.applyAsDouble(x, y);
}
}
Solution 1:[1]
The lambda expression is not a member of the enum
, so it cannot access member variables from the enum
directly. It also has no access to protected
and private
members of the enum. Also, at the point where the lambda is passed to the constructor, the member variables of the enum
are not in scope.
A possible solution is to pass symbol
as a third parameter to the lambda expression, but that means you'll have to use a different functional interface than DoubleBinaryOperator
.
For example:
interface CalculationOperation {
double calculate(double x, double y, String symbol);
}
public enum Operation {
PLUS("+", (x, y, symbol) -> {
System.out.println(symbol);
return x + y;
}),
MINUS("-", (x, y, symbol) -> x - y),
TIMES("*", (x, y, symbol) -> x * y),
DIVIDE("/", (x, y, symbol) -> x / y);
Operation(String symbol, CalculationOperation op) {
this.symbol = symbol;
this.op = op;
}
public String getSymbol() {
return symbol;
}
protected final String symbol;
private final CalculationOperation op;
public double apply(double x, double y) {
return op.calculate(x, y, symbol);
}
}
Solution 2:[2]
Alternatively:
import java.util.function.DoubleBinaryOperator;
import java.util.function.Supplier;
public class Test {
public enum Operation {
PLUS("+", (x, y) -> x + y, "verbose"),
MINUS("-", (x, y) -> x - y),
TIMES("*", (x, y) -> x * y),
DIVIDE("/", (x, y) -> x / y);
Operation(String symbol, DoubleBinaryOperator op) {
this(symbol, op, null);
}
Operation(String symbol, DoubleBinaryOperator op, String command) {
this.symbol = symbol;
this.op = op;
if("verbose".equalsIgnoreCase(command))
operation = verboseWrapper;
else
operation = silentWrapper;
}
public String getSymbol() {
return symbol;
}
protected String symbol;
private DoubleBinaryOperator op;
private Supplier<DoubleBinaryOperator> verboseWrapper = (() -> {System.out.println(symbol); return op; });
private Supplier<DoubleBinaryOperator> silentWrapper = (() -> {return op; });
private final Supplier<DoubleBinaryOperator> operation;
public double apply(double x, double y) {
return operation.get().applyAsDouble(x, y);
}
}
public static void main(String [] args) {
Operation plus = Operation.PLUS;
plus.apply(1, 3);
Operation minus = Operation.MINUS;
minus.apply(1, 3);
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Jesper |
Solution 2 |