Chris Mullen
Chris Mullen

Reputation: 11

How to correct Arraylist index out of bounds for length error in Java

I am writing a program for school which acts as a cash register. I am asking for input for prices of items and playing them into an ongoing ArrayList until the user enters -1 or 0. 0 is to re-enter the previous price in case of mistake and -1 terminates the loop.

I am getting the

java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0

error when I try to run my code. I have to include a method called removeLastEntry(), which will remove the last price entered into the array upon a 0 being entered by the user. How can I ensure the array is populated and I am indeed removing the last entry?

I am running Java 11 in Eclipse.

The code runs fine without the method being used, as I reduce my counter and in the next iteration of the loop, the previous array location is overwritten, regardless whether it has been removed or not. The method itself is set to remove ArrayList.size()-1 so that it removes the last entry. I have tried this with -2, and 0, and it still runs out of bounds.

I read through previous questions and many people had not populated the array. So I ran a print stub to make sure that the ArrayList has been properly populated, and it has: when two items were placed into the ArrayList size was equal to 2. The error code also goes up the more items I place into the code but is always items - 1 index out of bounds at items - 1 length I'm sure I'm making a rookie mistake but I'm unable to find it and it is driving me insane!

for full error context:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0 at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64) at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70) at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248) at java.base/java.util.Objects.checkIndex(Objects.java:372) at java.base/java.util.ArrayList.get(ArrayList.java:458) at C_M_iDeaProject.main(C_M_iDeaProject.java:76)

// declare our array list which will hold our prices!
ArrayList<Double> prices = new ArrayList<Double>();


// declaring variables to terminate loop, count prices, total prices, and current entry for conditions
        int counter  = 0;
        double entry = 0;
        double total = 0;

// our loop to continuously add prices to the array list from input
while (entry != -1) {

    System.out.println("Enter a price for item #" + (counter+1) + ": ");
    entry = myInput.nextDouble();

// if the entry is a price we will add it to prices and continue with the loop

    if (entry != 0 && entry != -1) {
            prices.add(entry);
            total += entry;
            counter++;
    }

//if the entry is 0 we will revert back to the previous iteration to re-add

    else if (entry == 0.0) {
        total -= prices.get(counter-1);
        removeLastEntry(prices);
        counter--;
    }

public static void removeLastEntry(ArrayList<Double> anArrayList) {
    anArrayList.remove(anArrayList.size()-1);
}

Upvotes: 1

Views: 12206

Answers (2)

sashimi
sashimi

Reputation: 1304

We solve the issue by checking if the list is already empty before attempting to delete last element in list - just in case the first value you receive is a zero :) We edited the original code to encapsulate behaviour regarding conventions (-1 to exit, 0 to remove last value) and avoid violating that principle every time we need to check.

    List<Double> prices = new ArrayList<Double>();

    // declaring variables to terminate loop, count prices, total prices, and current entry for conditions
    int counter  = 0;
    double entry = 0;
    double total = 0;

    // our loop to continuously add prices to the array list from input
    while (!isExit(entry)) {
        System.out.println(String.format("Enter a price for item # %s: ", counter+1));
        entry = myInput.nextDouble();

    // if the entry is a price we will add it to prices and continue with the loop
        if(isExit(entry)){
            //TODO exit
        }
        if(isRemove(entry)){
            if(!list.isEmpty()){
                total -= removeLastEntry(prices);
                counter--;
            }
        }else{
            prices.add(entry);
            total += entry;
            counter++;
        }

    }

    private boolean isExit(double value){
        return value==-1;
    }

    private boolean isRemove(double entry){
        return entry==0;
    }

    public static double removeLastEntry(List<Double> list) {
        double last = list.get(list.size()-1);
        list.remove(list.size()-1)
        return last;
    }

Upvotes: 0

Benjamin Urquhart
Benjamin Urquhart

Reputation: 1649

You can add a check to see if the list is empty:

// declare our array list which will hold our prices!
ArrayList<Double> prices = new ArrayList<Double>();


// declaring variables to terminate loop, count prices, total prices, and current entry for conditions
        int counter  = 0;
        double entry = 0;
        double total = 0;

// our loop to continuously add prices to the array list from input
while (entry != -1) {

    System.out.println("Enter a price for item #" + (counter+1) + ": ");
    entry = myInput.nextDouble();

// if the entry is a price we will add it to prices and continue with the loop

    if (entry != 0 && entry != -1) {
            prices.add(entry);
            total += entry;
            counter++;
    }

//if the entry is 0 we will revert back to the previous iteration to re-add

    else if (entry == 0.0) {
        total -= prices.get(counter-1);
        removeLastEntry(prices);
        counter--;
    }

public static void removeLastEntry(ArrayList<Double> anArrayList) {
    if(!anArrayList.isEmpty()) {
        anArrayList.remove(anArrayList.size()-1);
    }
}

Upvotes: 0

Related Questions