Android - 应该正常运行的代码中的错误

时间:2016-10-22 08:59:46

标签: android android-studio indexoutofboundsexception

我在这里有一些代码,我非常确定应该使用的计算器(我记得它在过去工作),但是它正在表现。

我已检查了所有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{}语句应该ERROR输出到textViewError而不是textViewCalcPrevRes

  3. 这里是方案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异常,但我真的不确定如何/为什么。

    有什么想法吗?

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

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

2 个答案:

答案 0 :(得分:2)

只需在代码中反复记录您的arrayList大小。你会知道它什么时候是空的。

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

答案 1 :(得分:0)

原来我犯了一个菜鸟错误,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");
    }
}