用 BinaryOperator 替换 switch
Replacing switch by BinaryOperator
我正在尝试用 BinaryOperator
功能接口替换算术运算的通用开关。
基本方法是:
private static int computeOne(int res, String operand, String operation) {
int number = Integer.parseInt(operand);
switch (operation) {
case "+":
res += number;
break;
case "-":
res -= number;
break;
case "*":
res *= number;
break;
case "/":
res = (number != 0 ? res / number : Integer.MAX_VALUE);
break;
default:
res = 0;
System.out.println("unknown operation");
}
return res;
}
据我所知,写这样的东西是必要的:
BinaryOperator<Integer> action = (a,b) -> computeExpression(a + operation + b);
action.apply(res, operand);
但我不明白如何避免 computeExpression
中的 switch
与 computeOne
相同。
算术运算符不能是变量。
通过在实际代码中使用或不使用功能接口,您将具有相同的约束:将 String
运算符转换为算术运算符。
此外,实际上在 computeOne()
中你接受一个 int
和两个 String
作为参数,你 return 接受一个 int
.
BinaryOperator<Integer>
接受两个 Integer
和 return 一个 Integer
.
所以它不兼容。
您需要 TriFunction
但它不存在。
创建您自己的功能界面,例如 TriFunction<T,U,V,R>
或减少传递给函数的参数数量。
这是一个使用枚举 Operator
结合 BiFunction
的示例,它执行与您的实际方法相同的操作。
请注意,由于运算符现在由负责执行函数的枚举 Operator
表示,因此该函数现在只需要两个参数:Integer
和 String
,您将它们转换为 int
.
所以 BiFunction<Integer, String, Integer>
没问题。
public enum Operator{
ADD("+", (a,b) -> a + Integer.parseInt(b)),
SUBSTRACT("-", (a,b) -> a - Integer.parseInt(b)),
MULTIPLY("*", (a,b) -> a * Integer.parseInt(b)),
// ...
DEFAULT("", (a,b) -> 0);
public BiFunction<Integer, String, Integer> function;
private String symbol;
Operator(String symbol, BiFunction<Integer, String, Integer> function){
this.symbol = symbol;
this.function = function;
}
public int compute(int actualValue, String operand){
return function.apply(actualValue, operand);
}
public static Operator of(String symbol) {
for (Operator value : values()) {
if (symbol.equals(value.symbol)) {
return value;
}
}
return Operator.DEFAULT;
}
}
您可以创建这样的操作:
int res = 10;
String operand = "15";
String symbol = "+";
res = Operator.of(symbol).compute(res, operand);
可以为每个算术运算定义一个BinaryOperator<Integer>
:
// a = operand 1
// b = operand 2
(a, b) -> a * b;
(a, b) -> a + b;
(a, b) -> a / b;
(a, b) -> a - b;
然后你可以应用一个传递 2 个参数:
// result = operation.apply(a, b);
int result = ((BinaryOperator<Integer>) ((a, b) -> a * b)).apply(2, 2);
我会使用枚举来枚举这些操作:
class Test {
public static void main(String[] args) {
System.out.println(computeOne(4, "2", "/")); // 2
System.out.println(computeOne(4, "2", "*")); // 8
System.out.println(computeOne(4, "2", "-")); // 2
System.out.println(computeOne(4, "2", "+")); // 6
}
private static int computeOne(int res, String operand, String operation) {
return Operation.getOperationBySymbol(operation)
.getBinaryOperator()
.apply(res, Integer.parseInt(operand));
}
private enum Operation {
// operation = symbol, action
MULTIPLICATION("*", (a, b) -> a * b),
ADDITION("+", (a, b) -> a + b),
SUBTRACTION("-", (a, b) -> a - b),
DIVISION("/", (a, b) -> a / b);
private final BinaryOperator<Integer> binaryOperator;
private final String symbol;
Operation(String symbol, BinaryOperator<Integer> binaryOperator) {
this.symbol = symbol;
this.binaryOperator = binaryOperator;
}
public BinaryOperator<Integer> getBinaryOperator() {
return binaryOperator;
}
public String getSymbol() {
return symbol;
}
public static Operation getOperationBySymbol(String symbol) {
for (Operation operation : values()) {
if (operation.getSymbol().equals(symbol)) {
return operation;
}
}
throw new IllegalArgumentException("Unknown symbol: " + symbol);
}
}
}
您也可以 "simplify" 它带有 BiFunction<BinaryOperator<?>, Pair<?, ?>, ?>
:
// BiFunction<Operator, Operands, Result>
// Operator = BinaryOperator<?>
// Operands = Pair<?, ?>
BiFunction<BinaryOperator<Integer>, Pair<Integer, Integer>, Integer> f =
(operator, operands) ->
operator.apply(operands.getKey(), operands.getValue());
f.apply((a, b) -> a + b, new Pair<>(2, 2)); // 4
我正在尝试用 BinaryOperator
功能接口替换算术运算的通用开关。
基本方法是:
private static int computeOne(int res, String operand, String operation) {
int number = Integer.parseInt(operand);
switch (operation) {
case "+":
res += number;
break;
case "-":
res -= number;
break;
case "*":
res *= number;
break;
case "/":
res = (number != 0 ? res / number : Integer.MAX_VALUE);
break;
default:
res = 0;
System.out.println("unknown operation");
}
return res;
}
据我所知,写这样的东西是必要的:
BinaryOperator<Integer> action = (a,b) -> computeExpression(a + operation + b);
action.apply(res, operand);
但我不明白如何避免 computeExpression
中的 switch
与 computeOne
相同。
算术运算符不能是变量。
通过在实际代码中使用或不使用功能接口,您将具有相同的约束:将 String
运算符转换为算术运算符。
此外,实际上在 computeOne()
中你接受一个 int
和两个 String
作为参数,你 return 接受一个 int
.
BinaryOperator<Integer>
接受两个 Integer
和 return 一个 Integer
.
所以它不兼容。
您需要 TriFunction
但它不存在。
创建您自己的功能界面,例如 TriFunction<T,U,V,R>
或减少传递给函数的参数数量。
这是一个使用枚举 Operator
结合 BiFunction
的示例,它执行与您的实际方法相同的操作。
请注意,由于运算符现在由负责执行函数的枚举 Operator
表示,因此该函数现在只需要两个参数:Integer
和 String
,您将它们转换为 int
.
所以 BiFunction<Integer, String, Integer>
没问题。
public enum Operator{
ADD("+", (a,b) -> a + Integer.parseInt(b)),
SUBSTRACT("-", (a,b) -> a - Integer.parseInt(b)),
MULTIPLY("*", (a,b) -> a * Integer.parseInt(b)),
// ...
DEFAULT("", (a,b) -> 0);
public BiFunction<Integer, String, Integer> function;
private String symbol;
Operator(String symbol, BiFunction<Integer, String, Integer> function){
this.symbol = symbol;
this.function = function;
}
public int compute(int actualValue, String operand){
return function.apply(actualValue, operand);
}
public static Operator of(String symbol) {
for (Operator value : values()) {
if (symbol.equals(value.symbol)) {
return value;
}
}
return Operator.DEFAULT;
}
}
您可以创建这样的操作:
int res = 10;
String operand = "15";
String symbol = "+";
res = Operator.of(symbol).compute(res, operand);
可以为每个算术运算定义一个BinaryOperator<Integer>
:
// a = operand 1
// b = operand 2
(a, b) -> a * b;
(a, b) -> a + b;
(a, b) -> a / b;
(a, b) -> a - b;
然后你可以应用一个传递 2 个参数:
// result = operation.apply(a, b);
int result = ((BinaryOperator<Integer>) ((a, b) -> a * b)).apply(2, 2);
我会使用枚举来枚举这些操作:
class Test {
public static void main(String[] args) {
System.out.println(computeOne(4, "2", "/")); // 2
System.out.println(computeOne(4, "2", "*")); // 8
System.out.println(computeOne(4, "2", "-")); // 2
System.out.println(computeOne(4, "2", "+")); // 6
}
private static int computeOne(int res, String operand, String operation) {
return Operation.getOperationBySymbol(operation)
.getBinaryOperator()
.apply(res, Integer.parseInt(operand));
}
private enum Operation {
// operation = symbol, action
MULTIPLICATION("*", (a, b) -> a * b),
ADDITION("+", (a, b) -> a + b),
SUBTRACTION("-", (a, b) -> a - b),
DIVISION("/", (a, b) -> a / b);
private final BinaryOperator<Integer> binaryOperator;
private final String symbol;
Operation(String symbol, BinaryOperator<Integer> binaryOperator) {
this.symbol = symbol;
this.binaryOperator = binaryOperator;
}
public BinaryOperator<Integer> getBinaryOperator() {
return binaryOperator;
}
public String getSymbol() {
return symbol;
}
public static Operation getOperationBySymbol(String symbol) {
for (Operation operation : values()) {
if (operation.getSymbol().equals(symbol)) {
return operation;
}
}
throw new IllegalArgumentException("Unknown symbol: " + symbol);
}
}
}
您也可以 "simplify" 它带有 BiFunction<BinaryOperator<?>, Pair<?, ?>, ?>
:
// BiFunction<Operator, Operands, Result>
// Operator = BinaryOperator<?>
// Operands = Pair<?, ?>
BiFunction<BinaryOperator<Integer>, Pair<Integer, Integer>, Integer> f =
(operator, operands) ->
operator.apply(operands.getKey(), operands.getValue());
f.apply((a, b) -> a + b, new Pair<>(2, 2)); // 4