简体   繁体   中英

ArrayList IndexOutOfBoundsException while processing user input

I am trying to write a program that uses a sentinal contolled do-while loop, that repeatedly asks the user for positive integers.

The loop should end when a negative value is entered by the user. After the loop completes, your program should print out the minimum, maximum, average, and count of the positive numbers that were entered by the user.

However when I run the program, I get the error:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 3, Size: 3
    at java.util.ArrayList.rangeCheck(Unknown Source)
    at java.util.ArrayList.get(Unknown Source)
    at posNeg.main(posNeg.java:31)

I have searched for answers but none of them seem to be working. Most just suggest removing the = from the for (int i = 0; i <= (count); i++) { .

Anyway, here is the full code:

import java.util.*;
import java.lang.Math;

public class posNeg {

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        ArrayList list = new ArrayList();
        int num;
        int count = 0;

        do{
            System.out.println("enter pos nums (or a neg num to quit): ");
            num = sc.nextInt();
            list.add(num);
            count++;
        } while (num >= 0);

        Iterator it = list.iterator();

        list.remove(list.get(count-1));

        Object max = Collections.max(list);
        Object min = Collections.min(list);

        System.out.print(list);

        int tot = 0;
        for (int i = 0; i <= (count); i++) {
            Object piece = list.get(i);
            int piecenum = ((Number) piece).intValue();
            tot = tot + piecenum;
        }

        double avg;
        avg = tot/count;

        System.out.println("the max is "+max+". the min is "+min+". the avg is "+avg);
    }
}

When you build your list, you increment count.

So after building count==list.size() .

After that you remove one item from the listbut don't change count .

So count==list.size()-1 .

So your loop should be

for (int i = 0; i <= count-2; i++) {

because you have items from index 0 to count-2 .

But instead of maintaining a count, you could simply do

for (int i = 0; i<list.size(); i++) {

Look at this loop:

for (int i = 0; i <= (count); i++) {

At this point the list only has count - 1 items, but you're looping count + 1 times. For the sake of sanity you should decrement count after the call to remove , and then also change the loop to the more idiomatic:

for (int i = 0; i < count; i++) {

Or, rather more simply:

for (Number number : list) {
    ...
}

This will only work after making list generic though:

List<Number> list = new ArrayList<Number>();

You should really be using generics for collections.

Better do it this way....

for (int i = 0; i < (count); i++) {


 }

Or

Use the For-Each loop

for(Number n : list){


}

The bug is with count, as others have noted. I suggest using a conditional break; in your input loop to avoid adding the negative value to the list, and incrementing count. in the first place. You will still need to replace <= with < whenever using a language with zero based indexing.

try this list.size instead of count

for (int i = 0; i < list.size(); i++) {
            Object piece = list.get(i);
            int piecenum = ((Number) piece).intValue();
            tot = tot + piecenum;
        }

Some suggestions,,,

    do{
        System.out.println("enter pos nums (or a neg num to quit): ");
        num = sc.nextInt();
        if (num >= 0)
           break;
        list.add(num);
    }while (true);

.. and for the next loop

    int tot = 0;
    for (int i : list ) {
        //do your stuff
    }

.. but you should really use a typed list

  List<int> list = new ArrayList<int>()

... or something like that

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM