我正在学习Java,我的第一个项目是计算器,但是我遇到了麻烦。我想让我的计算器让我输入一个数字然后点击一个操作员(+, - ,x,/),输入另一个数字,然后再次点击一个操作员并让显示更新并能够保持这种状态。 / p>
示例,我希望能够点击以下内容并让它在每次第一次触及操作符后显示总数:
a + b / c - d =
我看到的代码(对我而言)似乎应该有效,但事实并非如此。我做错了什么?
以下是我遇到操作员时使用的代码。默认情况下,wait设置为false。在类中运行一次后,将存储value1并将wait设置为true,这样可以正常工作。从那里它似乎没有正常工作:
class OperatorListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
String input = event.getActionCommand();
// Set display as string
String s = display.getText();
if (!wait) {
// Convert first input string to double
try {
value1 = Double.valueOf(s.trim()).doubleValue();
} catch (NumberFormatException nfe) {
System.out.println("NumberFormatException: " + nfe.getMessage());
}
dec = false;
} else {
// Convert second input string to double
try {
value2 = Double.valueOf(s.trim()).doubleValue();
} catch (NumberFormatException nfe) {
System.out.println("NumberFormatException: " + nfe.getMessage());
}
// Determine operation to be performed
if (operator == "add") {
value1 = Operators.add(value1, value2);
} else if (operator == "subtract") {
value1 = Operators.subtract(value1, value2);
} else if (operator == "multiply") {
value1 = Operators.multiply(value1, value2);
} else if (operator == "divide") {
value1 = Operators.divide(value1, value2);
}
// Convert final value to string and display
display.setText(Double.toString(value1));
dec = false;
}
// Determine operator hit
if (input.equals("+")) {
operator = "add";
} else if (input.equals("-")) {
operator = "subtract";
} else if (input.equals("x")) {
operator = "multiply";
} else if (input.equals("/")) {
operator = "divide";
}
// Set wait
wait = true;
}
}
编辑:更新了代码以修复一些混淆并更新if语句。即使在此之后仍然存在同样的问题。此外,完整的来源可用here
答案 0 :(得分:4)
一些建议。
首先,我建议在使用boolean
作为if
语句的条件时,避免与true
和false
进行比较 - 只有两种状态boolean
无论如何。此外,由于只有两种状态,而不是使用else if (false)
,else
就足够了:
if (condition == true)
{
// when condition is true
}
else if (condition == false)
{
// when condition is false
}
可以改写为:
if (condition)
{
// when condition is true
}
else
{
// when condition is false
}
其次,不是比较字符串文字"add"
,"subtract"
等,而是尝试使用常量(final
变量)或enum
s。正在进行String
比较,例如(operator == "add")
正在执行检查,以查看字符串文字"add"
和operator
变量是否引用到相同的对象,而不是值是否相同。因此,在某些情况下,您可能将operator
设置为"add"
,但比较可能不是true
,因为字符串文字引用了单独的对象。一个简单的解决方法是:
final String operatorAdd = "add";
// ...
if (input.equals("+"))
operator = operatorAdd;
// ...
if (operator == operatorAdd)
// ...
现在,operator
的分配和operator
的比较都引用了常量operatorAdd
,因此比较可以使用==
而不是{{} 1}}方法。
第三,因为这看起来像计算器的类型并不真正需要两个操作数(即equals()
),而是一个作用于存储值的单个操作数(即operand1 + operand2
) ,拥有一个保存当前值的变量,另一个保存运算符的变量,以及一个根据当前运算符和操作数执行的方法,可能会更容易。 (或多或少是对accumulator machine或1操作数计算机的想法。)
基本操作方法是:
operand + currentValue
。currentValue
。operand
设置为计算结果。每个步骤都应该检查上一步是否发生 - 确保指定了一个操作(currentValue
设置为有效的操作符),然后输入的下一个值变为operator
。计算器类似于state machine,从一个步骤到另一个步骤必须按特定顺序执行,否则它将不会进入下一步。
所以,计算器可能是这样的(伪代码!):
operand
虽然上面的代码使用单个循环并且不像基于事件的GUI模型那样工作,但它应该概述运行计算器所需的步骤。
答案 1 :(得分:3)
每当您输入运算符时,您的代码都将执行此操作:
Double.valueOf(s.trim())
用于设置value1
或value2
(取决于wait
)。这将引发异常,因为运算符不能被解析为双精度数。在尝试将输入解析为数字之前,您可能会更好地检查运算符 first 。然后,如果它是一个运算符,您可以跳过数字解析部分。
还要考虑如果有人要连续输入两个数字或两个运算符会发生什么。
答案 2 :(得分:1)
正如Greg所说,无论输入什么,无论当前的程序状态如何,你总是解析数字。您需要更干净地跟踪程序状态。我假设你的代码有“String s = output.getText();”你的意思是“String s = input.getText();”。
另请注意
if (wait == false) { // Stuff for !wait } else if (wait == true) { // Stuff for wait }
不必要地多余。您可以将其替换为:
if (!wait) { // Stuff for !wait } else { // Stuff for wait }
您应该检查输入字符串以查看它是否是操作符,如果不是,则确保它是数字。编写infix计算器(正确处理优先级)并非易事。
答案 3 :(得分:0)
在搜索到高低后,我终于确定问题不在我提供的代码中。我有一个“等待=假”;在我的NumberListener类中,搞砸了执行。为了解决这个问题,我创建了两个独立的等待变量,到目前为止一切正常。
感谢帮助和提示人员,给大家+1尝试。
答案 4 :(得分:-1)
您可以在Java中使用脚本引擎。如果你没有Java 6+,你可以使用Rhino做同样的事情。然后,您可以在JavaScript中执行任何操作
// create a script engine manager
ScriptEngineManager factory = new ScriptEngineManager();
// create a JavaScript engine
ScriptEngine engine = factory.getEngineByName("JavaScript");
// expose a, b, c, d
engine.put("a", 1);
engine.put("b", 8);
engine.put("c", 2);
engine.put("d", 3);
// evaluate JavaScript code from String
Number value = (Number) engine.eval("a + b / c * d");
System.out.println(value);