【问题标题】:Android - Errors in code that should be workingAndroid - 应该可以工作的代码错误
【发布时间】: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");
    }
}

我将给出两个场景来帮助说明我的问题:

  1. arrayList = [2,+,2]; 运行此方法时,textViewCalcPrevRes 显示 4

  2. arrayList = [2,+,2,+,2]; 运行此方法时,textViewCalcPrevRes 显示 ERROR,因为该方法抛出异常并在控制台中打印堆栈跟踪(请参阅下一个代码块)。真正奇怪的是catch{} 语句应该输出ERRORtextViewError 而不是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 异常,但我真的不确定如何/为什么。

有什么想法吗?

编辑:进一步的“调查”表明异常的起源来自这行代码(标有//--&gt;):

// 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


【解决方案1】:

简单地说,在代码中一次又一次地记录你的 arrayList 大小。你会知道它什么时候是空的。

Log.d("Buggy List Size ",  arrayList.size()+"");

【讨论】:

  • 你能解释一下如何实现这个来调试代码吗?我是调试新手。
  • 我想通了,你帮我修复了我的代码!谢谢。
  • 也开始学习调试技术。从长远来看,这将对您有所帮助。
【解决方案2】:

原来我犯了一个新手错误,CHECK IF DECIMAL 循环在while 循环内,这意味着一旦进行了第一次计算,它就会尝试输出结果。它不计算2+2+2,而是只计算2+2,然后清除arrayList,导致IndexOutOfBounds异常。

这是固定代码(CHECK IF DECIMAL 循环在 while 循环之外,应该是这样)

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]
                    Log.d("BuggyListSizeB4Remove1", arrayList.size()+"");
                    arrayList.remove(2); //[2,+,*,4,-,3]
                    Log.d("BuggyListSizeB4Remove2", arrayList.size()+"");
                    arrayList.remove(2); //[2,+,4,-,3]
                    Log.d("BuggyListSizeB4Remove3", arrayList.size()+"");
                    arrayList.remove(2); //[2,+,-,3]
                    Log.d("BuggyListSizeAfter3", arrayList.size()+"");
                    arrayList.add(2, Double.toString(calc)); //[2,+,12,-,3]
                    c = arrayList.size(); // size(c) = 5
                    Log.d("BuggyListSize AfterCalc", arrayList.size()+"");
                } 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
                    Log.d("BuggyListSizeB4Remove1", arrayList.size()+"");
                    arrayList.remove(0); //[+,12,-,3]
                    Log.d("BuggyListSizeB4Remove2", arrayList.size()+"");
                    arrayList.remove(0); //[12,-,3]
                    Log.d("BuggyListSizeB4Remove3", arrayList.size()+"");
                    arrayList.remove(0); //[-,3]
                    Log.d("BuggyListSizeAfter3", arrayList.size()+"");
                    arrayList.add(0, Double.toString(calc)); //[14,-,3]
                    c = arrayList.size(); // size(c) = 3
                    Log.d("BuggyListSize AfterCalc", arrayList.size()+"");
                }
            }
            // 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
                Log.d("BuggyListSizeB4Remove1", arrayList.size()+"");
                arrayList.remove(0); //[-,3]
                Log.d("BuggyListSizeB4Remove2", arrayList.size()+"");
                arrayList.remove(0); //[3]
                Log.d("BuggyListSizeB4Remove3", arrayList.size()+"");
                arrayList.remove(0); //[null]
                Log.d("BuggyListSizeAfter3", arrayList.size()+"");
                arrayList.add(0, Double.toString(calc)); // [9]
                c = arrayList.size(); // size(c) = 1
                prevCalc = Double.toString(calc);
                Log.d("BuggyListSize AfterCalc", arrayList.size()+"");
            }
        }
        //CHECK IF DECIMAL
        //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();
        }
        //output to textViews
            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");
    }
}

【讨论】:

    猜你喜欢
    • 2013-10-09
    • 1970-01-01
    • 2016-10-01
    • 1970-01-01
    • 2020-08-05
    • 1970-01-01
    • 2022-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多