0

In my Android Applicatio I have an Array of Strings from whom I want to remove Strings.

List<String> categoryList = new ArrayList<String>(Arrays.asList(dishCategory));
        for (int i = 0; i < dishCategory.length; i++) {
            if (dishCategory[i].equals("Beilagen")) {
                categoryList.remove(i);
            }
            String[] dishCategory = categoryList.toArray(new String[categoryList.size()]);
        }

But when I try it it givees:

 FATAL EXCEPTION: main
    Process: de.hswt.fuca, PID: 19818
   java.lang.IndexOutOfBoundsException: Invalid index 14, size is 13
 at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
at java.util.ArrayList.remove(ArrayList.java:403)

4 Answers 4

3

This is because you're modifying the List that you iterate over. An example of where this goes wrong is if your List is 2 items long:

["Beilagen", "Beilagen"]

The first iteration removes the item at index 0. This modifies the List so that it looks like this:

["Beilagen"]

Then the second iteration wants to remove the item at index 1, but the length of the list is 1 so this will produce an IndexOutOfBoundsException like you see.

A quick and dirty fix for this could be to make the number of items you want to iterate over a variable that you modify during removals like so:

List<String> categoryList = new ArrayList<String>(Arrays.asList(dishCategory));
int upperLimit = dishCategory.length;
for (int i = 0; i < upperLimit; i++) {
    if (dishCategory[i].equals("Beilagen")) {
        categoryList.remove(i);
        upperLimit--;
        i--;
    }
    String[] dishCategory = categoryList.toArray(new String[categoryList.size()]);
}

but I'd recommend using listIterator() if you want clean code, as it was made for this sort of purpose.

Sign up to request clarification or add additional context in comments.

Comments

0

My suggestion is to use the built in Iterator that is part of your ArrayList to iterate through your array. Here is a simple implementation that will do what you want. Also change your List back to an array after you finish removing all of the elements. This will make your runtime O(n) instead of the current O(n^2)

List<String> categoryList = new ArrayList<String>(Arrays.asList(dishCategory));
Iterator<String> i = categoryList.iterator();
while (i.hasNext()) {
   String s = i.next();
   if (s.equals("Beilagen")) {
       i.remove();
   }
}
String [] dishCategory = categoryList.fromArray(String[categoryList.size()]); 

If your aren't a fan of Iterators changing your limit on your for loop to be the List.size() would also work since it will be reevaluated with each pass through the for loop though an i-- will be needed since the indexes are reevaluated after a remove. Here is that code:

List<String> categoryList = new ArrayList<String>(Arrays.asList(dishCategory));
for (int i = 0; i < categoryList.size(); i++) {
    if (categoryList.get(i).equals("Beilagen")) {
       categoryList.remove(i);
       i--;
    }      
}
String [] dishCategory = categoryList.fromArray(String[categoryList.size()]); 

Comments

0
List<String> categoryList = new ArrayList<String>(Arrays.asList(dishCategory));
categoryList.removeAll(Arrays.asList("Beilagen"));
dishCategory = categoryList.toArray(dishCategory);

Comments

-1

Change:

for (int i = 0; i < dishCategory.length; i++) {

to:

for (int i = 0; i < dishCategory.length - 1; i++) {

Remember that all the arrays are 0-indexed so you never have an index as big as the actual length of the structure.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.