【发布时间】:2016-10-22 08:59:45
【问题描述】:
我这里有一些计算器代码,我很确定它应该可以工作(我记得它过去可以工作),但它正在发挥作用。
我检查了所有 arrayList.get() 以确保它们指向正确的索引,并且每个循环有正确数量的 arrayList.remove()。
我唯一能想到的另一件事是,检查结果是否为小数的if 循环(就在方法的底部附近)可能会造成麻烦。
代码如下:
public void onClickEquals (View view) {
TextView textViewError = (TextView) findViewById(R.id.textViewCalcPrevRes);
TextView textViewCalcPrevRes = (TextView) findViewById(R.id.textViewCalcPrevRes);
TextView textViewCalcCurrExp = (TextView) findViewById(R.id.textViewCalcCurrExp);
TextView textViewCalcPrevExp = (TextView) findViewById(R.id.textViewCalcPrevExp);
double calc = 0;
String calcOutputStr = "";
String tempString = "";
int c = arrayList.size();
try {
textViewError.setText("");
//i.e. array [2,+,3,*,4,-,3] size(c) = 7, so [2,+,3,*,4,-,3]
while (c != 1) {
if (c > 3) {
if (arrayList.get(3).contains("×") || arrayList.get(3).contains("÷")) {
if (arrayList.get(3).contains("×")) {calc = Double.parseDouble(arrayList.get(2)) * Double.parseDouble(arrayList.get(4));}
if (arrayList.get(3).contains("÷")) {calc = Double.parseDouble(arrayList.get(2)) / Double.parseDouble(arrayList.get(4));}
//calc = 12 ;array = [2,+,3,*,4,-,3]
arrayList.remove(2); //[2,+,*,4,-,3]
arrayList.remove(2); //[2,+,4,-,3]
arrayList.remove(2); //[2,+,-,3]
arrayList.add(2, Double.toString(calc)); //[2,+,12,-,3]
c = arrayList.size(); // size(c) = 5
} else {
//[2,+,12,-,3]
if (arrayList.get(1).contains("+")) {calc = Double.parseDouble(arrayList.get(0)) + Double.parseDouble(arrayList.get(2));}
if (arrayList.get(1).contains("-")) {calc = Double.parseDouble(arrayList.get(0)) - Double.parseDouble(arrayList.get(2));}
if (arrayList.get(1).contains("×")) {calc = Double.parseDouble(arrayList.get(0)) * Double.parseDouble(arrayList.get(2));}
if (arrayList.get(1).contains("÷")) {calc = Double.parseDouble(arrayList.get(0)) / Double.parseDouble(arrayList.get(2));}
//calc = 14
arrayList.remove(0); //[+,12,-,3]
arrayList.remove(0); //[12,-,3]
arrayList.remove(0); //[-,3]
arrayList.add(0, Double.toString(calc)); //[14,-,3]
c = arrayList.size(); // size(c) = 3
}
}
// size(c) <= 3
else {
if (arrayList.get(1).contains("+")) {calc = Double.parseDouble(arrayList.get(0)) + Double.parseDouble(arrayList.get(2));}
if (arrayList.get(1).contains("-")) {calc = Double.parseDouble(arrayList.get(0)) - Double.parseDouble(arrayList.get(2));}
if (arrayList.get(1).contains("×")) {calc = Double.parseDouble(arrayList.get(0)) * Double.parseDouble(arrayList.get(2));}
if (arrayList.get(1).contains("÷")) {calc = Double.parseDouble(arrayList.get(0)) / Double.parseDouble(arrayList.get(2));}
//calc = 11
arrayList.remove(0); //[-,3]
arrayList.remove(0); //[3]
arrayList.remove(0); //[null]
arrayList.add(0, Double.toString(calc)); // [9]
c = arrayList.size(); // size(c) = 1
prevCalc = Double.toString(calc);
}
//CHECK IF DECIMAL - SHOULD BE OUTSIDE WHILE LOOP
//check if calc is a whole number; if yes, convert to string and enter into tempString, remove decimal and enter into calcOutputStr ready for display on screen.
if (calc % 1 == 0) {
tempString = Double.toString(calc);
if (tempString != null) {
tempString = tempString.substring(0, tempString.length() - 2);
}
calcOutputStr = tempString;
arrayList.clear();
}
//if calc is a decimal convert to string ready for display on screen.
else {
calcOutputStr = Double.toString(calc);
arrayList.clear();
}
}
textViewCalcPrevExp.setText(textViewCalcCurrExp.getText()); //copy text from textViewCalcCurrExp to textViewCalcPrevExp
textViewCalcCurrExp.setText(""); //remove text from textViewCalcCurrExp
textViewCalcPrevRes.setText(calcOutputStr); //display calc
stringInput = "";
stringInputWithOp="";
}
catch (Exception e) {
e.printStackTrace();
textViewCalcPrevExp.setText(textViewCalcCurrExp.getText());
textViewCalcCurrExp.setText("");
stringInput="";
stringInputWithOp="";
arrayList.clear();
textViewError.setText("ERROR");
}
}
我将给出两个场景来帮助说明我的问题:
arrayList = [2,+,2];运行此方法时,textViewCalcPrevRes显示4arrayList = [2,+,2,+,2];运行此方法时,textViewCalcPrevRes显示ERROR,因为该方法抛出异常并在控制台中打印堆栈跟踪(请参阅下一个代码块)。真正奇怪的是catch{}语句应该输出ERROR到textViewError而不是textViewCalcPrevRes。
这是场景 2 中输出到控制台的堆栈跟踪:
W/System.err: java.lang.IndexOutOfBoundsException: Index: 1, Size: 0
W/System.err: at java.util.ArrayList.get(ArrayList.java:411)
W/System.err: at com.st1.u3141294.sparkscientificcalculator.sparkMain$override.onClickEquals(sparkMain.java:126)
W/System.err: at com.st1.u3141294.sparkscientificcalculator.sparkMain$override.access$dispatch(sparkMain.java)
W/System.err: at com.st1.u3141294.sparkscientificcalculator.sparkMain.onClickEquals(sparkMain.java:0)
W/System.err: at java.lang.reflect.Method.invoke(Native Method)
W/System.err: at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
W/System.err: at android.view.View.performClick(View.java:5610)
W/System.err: at android.view.View$PerformClick.run(View.java:22260)
W/System.err: at android.os.Handler.handleCallback(Handler.java:751)
W/System.err: at android.os.Handler.dispatchMessage(Handler.java:95)
W/System.err: at android.os.Looper.loop(Looper.java:154)
W/System.err: at android.app.ActivityThread.main(ActivityThread.java:6077)
W/System.err: at java.lang.reflect.Method.invoke(Native Method)
W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
显然它抛出了 IndexOutOfBounds 异常,但我真的不确定如何/为什么。
有什么想法吗?
编辑:进一步的“调查”表明异常的起源来自这行代码(标有//-->):
// size(c) <= 3
else {
//-->if (arrayList.get(1).contains("+")) {calc = Double.parseDouble(arrayList.get(0)) + Double.parseDouble(arrayList.get(2));}
if (arrayList.get(1).contains("-")) {calc = Double.parseDouble(arrayList.get(0)) - Double.parseDouble(arrayList.get(2));}
if (arrayList.get(1).contains("×")) {calc = Double.parseDouble(arrayList.get(0)) * Double.parseDouble(arrayList.get(2));}
if (arrayList.get(1).contains("÷")) {calc = Double.parseDouble(arrayList.get(0)) / Double.parseDouble(arrayList.get(2));}
编辑:@Code-Apprentice:
如果我们使用场景 2 作为arrayList(即[2,+,2,+,2])的内容,那么我的代码应该可以工作。跟踪跟踪:
第一个代码块运行是因为c = arrayList.size() = 5,并且arrayList 中没有乘法/除法运算符,所以它会进入else 循环:
while (c != 1) {
if (c > 3) {
//here is code only run if there are multiplication or division operators in arrayList
} else {
if (arrayList.get(1).contains("+")) {calc = Double.parseDouble(arrayList.get(0)) + Double.parseDouble(arrayList.get(2));}
}
arrayList.remove(0); //bringing arrayList down to [+,2,+,2]
arrayList.remove(0); //then [2,+,2]
arrayList.remove(0); //then [+,2]
arrayList.add(0, Double.toString(calc)); //then adding 4 (calc) to arrayList[0] would give [4,+,2]
c = arrayList.size(); // therefore arrayList.size() = 3
}
现在,因为c = arrayList.size() = 3:
// size(c) <= 3
else {
//4+2
if (arrayList.get(1).contains("+")) {calc = Double.parseDouble(arrayList.get(0)) + Double.parseDouble(arrayList.get(2));}
}
//new value of calc = 6
arrayList.remove(0); //gives [+,2]
arrayList.remove(0); //gives [2]
arrayList.remove(0); //arrayList is now empty: [null]
arrayList.add(0, Double.toString(calc)); // arrayList populated with calc --> [6]
c = arrayList.size(); // size(c) = 1
prevCalc = Double.toString(calc); //puts this calculation into memory for next calculation if needed
【问题讨论】:
-
评论碰撞。
-
"索引:1,大小:0" 这意味着列表为空。您需要使用调试来弄清楚为什么会这样。
-
如果您需要进一步的帮助,请告诉我们是哪一行导致了崩溃。
-
不请自来的建议:findViewById() 很昂贵。您应该在 onCreate() 中执行这些调用一次并将引用保存为字段变量。
-
@Code-Apprentice 我编辑了 OP 以显示代码将运行。在我看来,看起来应该没有什么问题。查看帖子底部。
标签: android android-studio indexoutofboundsexception