如何在 Java 中创建包含运算符的变量?
How to create a variable that contains an Operator in Java?
我正在尝试用 30 行或更少的代码来编写我的 class(自我挑战)的程序。
程序要求用户进行简单的加法、除法、乘法或减法问题,然后玩家回答,冲洗并重复 10次,然后询问玩家是否要继续或结束程序。题型(add、mult等)随机选择
这样我就不需要使用巨大的switch case或者if-else树,我想知道有没有办法在变量中包含一个运算符,以后再用。
示例:
var operator = +;
int[] n = {1, 2};
System.out.println(n[0] operator n[1]);
输出为“3”
这就是我想做的事情的一个例子。这可能吗?
不,您不能直接这样做。您必须创建一个 表示 运算符的类型。
最常用的方法是使用枚举:
enum Operator {
PLUS {
@Override int operate(int a, int b) {
return a + b;
}
};
abstract int operate(int a, int b);
}
Operator operator = Operator.PLUS;
int[] n = {1, 2};
System.out.println(operator.operate(n[0], n[1]));
无法将运算符分配给变量。
in 30 lines or less ... the program asks the user a simple addition, division, multiplication, or subtraction
如果你想用尽可能少的行来实现它,build-in 功能接口 将是一个不错的选择。为此,您需要 IntBinaryOperator
表示对两个 int
参数完成的操作。
功能接口可以通过使用 lambda expression or a method reference 来实现(此外,您也可以使用匿名内部 class 来实现,因为它不会更短).加法运算可以这样表示:
IntBinaryOperator add = Integer::sum; // or (i1, i2) -> i1 + i2
The type of question (add, mult, etc.) should be selected randomly
为此,首先,您需要定义一个 Random
对象。为了获得给定范围内的随机整数,请使用 nextInt()
方法,该方法需要 int
界限,并且 returns 从 0
到界限(独家):
rand.nextInt(RANGE)
为避免hard-coding,RANGE
应定义为全局常量。
因为您的应用程序必须与用户进行交互,所以每个 operation 都应该与将向用户公开的 name 相关联.
可以通过声明一个record
(一种特殊的class和 final
字段和auto-generated 构造函数,getters, hashCode/equals
, toString()
)。声明记录的语法非常简洁:
public record Operation(String name, IntBinaryOperator operation) {}
记录表示算术运算可以存储在列表中。您可以通过生成随机索引(从 0
到列表大小)来选择一个操作。
operations.get(rand.nextInt(operations.size()))
与普通的 getter 不同,编译器为记录生成的 getter 的名称将与其字段的名称相同,即 name()
和 operation()
.
为了使用从记录中检索到的函数,您需要对其调用方法applyAsInt()
,传递之前生成的两个数字。
这就是它的样子。
public class Operations {
public static final int RANGE = 100;
public static final Random rand = new Random();
public record Operation(String name, IntBinaryOperator operation) {}
public static final List<Operation> operations =
List.of(new Operation("add", Integer::sum), new Operation("sub", (i1, i2) -> i1 - i2),
new Operation("mult", (i1, i2) -> i1 * i2), new Operation("div", (i1, i2) -> i1 / i2));
public static void main(String[] args) {
// you code (instansiate a scanner, enclose the code below with a while loop)
for (int i = 0; i < 10; i++) {
Operation oper = operations.get(rand.nextInt(operations.size()));
int operand1 = rand.nextInt(RANGE);
int operand2 = rand.nextInt(RANGE);
System.out.println(operand1 + " " + oper.name() + " " + operand2); // exposing generated data to the user
int userInput = sc.nextInt(); // reading user's input
int result = oper.operation().applyAsInt(operand1,operand2); // exposing the result
System.out.println(result + "\n__________________");
}
// termination condition of the while loop
}
}
这是用户将看到的输出示例:
38 add 67
105 // user input
105
_____________________
97 sub 15
...
不幸的是java既不支持运算符重载也不支持中缀表示法,因此无法在源代码中这样做。
我正在尝试用 30 行或更少的代码来编写我的 class(自我挑战)的程序。
程序要求用户进行简单的加法、除法、乘法或减法问题,然后玩家回答,冲洗并重复 10次,然后询问玩家是否要继续或结束程序。题型(add、mult等)随机选择
这样我就不需要使用巨大的switch case或者if-else树,我想知道有没有办法在变量中包含一个运算符,以后再用。
示例:
var operator = +;
int[] n = {1, 2};
System.out.println(n[0] operator n[1]);
输出为“3”
这就是我想做的事情的一个例子。这可能吗?
不,您不能直接这样做。您必须创建一个 表示 运算符的类型。
最常用的方法是使用枚举:
enum Operator {
PLUS {
@Override int operate(int a, int b) {
return a + b;
}
};
abstract int operate(int a, int b);
}
Operator operator = Operator.PLUS;
int[] n = {1, 2};
System.out.println(operator.operate(n[0], n[1]));
无法将运算符分配给变量。
in 30 lines or less ... the program asks the user a simple addition, division, multiplication, or subtraction
如果你想用尽可能少的行来实现它,build-in 功能接口 将是一个不错的选择。为此,您需要 IntBinaryOperator
表示对两个 int
参数完成的操作。
功能接口可以通过使用 lambda expression or a method reference 来实现(此外,您也可以使用匿名内部 class 来实现,因为它不会更短).加法运算可以这样表示:
IntBinaryOperator add = Integer::sum; // or (i1, i2) -> i1 + i2
The type of question (add, mult, etc.) should be selected randomly
为此,首先,您需要定义一个 Random
对象。为了获得给定范围内的随机整数,请使用 nextInt()
方法,该方法需要 int
界限,并且 returns 从 0
到界限(独家):
rand.nextInt(RANGE)
为避免hard-coding,RANGE
应定义为全局常量。
因为您的应用程序必须与用户进行交互,所以每个 operation 都应该与将向用户公开的 name 相关联.
可以通过声明一个record
(一种特殊的class和 final
字段和auto-generated 构造函数,getters, hashCode/equals
, toString()
)。声明记录的语法非常简洁:
public record Operation(String name, IntBinaryOperator operation) {}
记录表示算术运算可以存储在列表中。您可以通过生成随机索引(从 0
到列表大小)来选择一个操作。
operations.get(rand.nextInt(operations.size()))
与普通的 getter 不同,编译器为记录生成的 getter 的名称将与其字段的名称相同,即 name()
和 operation()
.
为了使用从记录中检索到的函数,您需要对其调用方法applyAsInt()
,传递之前生成的两个数字。
这就是它的样子。
public class Operations {
public static final int RANGE = 100;
public static final Random rand = new Random();
public record Operation(String name, IntBinaryOperator operation) {}
public static final List<Operation> operations =
List.of(new Operation("add", Integer::sum), new Operation("sub", (i1, i2) -> i1 - i2),
new Operation("mult", (i1, i2) -> i1 * i2), new Operation("div", (i1, i2) -> i1 / i2));
public static void main(String[] args) {
// you code (instansiate a scanner, enclose the code below with a while loop)
for (int i = 0; i < 10; i++) {
Operation oper = operations.get(rand.nextInt(operations.size()));
int operand1 = rand.nextInt(RANGE);
int operand2 = rand.nextInt(RANGE);
System.out.println(operand1 + " " + oper.name() + " " + operand2); // exposing generated data to the user
int userInput = sc.nextInt(); // reading user's input
int result = oper.operation().applyAsInt(operand1,operand2); // exposing the result
System.out.println(result + "\n__________________");
}
// termination condition of the while loop
}
}
这是用户将看到的输出示例:
38 add 67
105 // user input
105
_____________________
97 sub 15
...
不幸的是java既不支持运算符重载也不支持中缀表示法,因此无法在源代码中这样做。