Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why retainAll in ArrayList throws an Exception

Tags:

java

I have created a new ArrayList using subList Method.Now when I try to perform intersection operation using retainAll it Throws following exception

retainAll() Method works for Below Code

List<Integer> arrNums1 = new ArrayList<Integer>();
arrNums1.add(1);
arrNums1.add(2);
arrNums1.add(3);

List<Integer> arrNums2 = arrNums1.subList(0, 1);
arrNums2.retainAll(arrNums1);

But when i try to apply retainAll for Below code it generates Exception as Below

Java Code

public class Generics1
{   
 public static void main(String[] args)
 {
       List<Fruits> arrFruits = new ArrayList<Fruits>();

        Fruits objApple  = new Apple();
        Fruits objOrange = new Orange();
        Fruits objMango  = new Mango();

        arrFruits.add(objApple);
        arrFruits.add(objOrange);
        arrFruits.add(objMango);

        List<Fruits> arrNewFruits = arrFruits.subList(0, 1);

        System.out.println(arrFruits.retainAll(arrNewFruits));
  }
}

class Fruits {}

class Apple extends Fruits {}

class Orange extends Fruits {}

class Mango extends Fruits {}

ERROR

enter image description here

like image 326
Java Beginner Avatar asked Jul 10 '13 07:07

Java Beginner


People also ask

What is retainAll in ArrayList?

The retainAll() method of ArrayList is used to remove all the array list's elements that are not contained in the specified collection or retains all matching elements in the current ArrayList instance that match all elements from the Collection list passed as a parameter to the method.

What does retainAll do in Java?

The Java ArrayList retainAll() method retains only those elements in the arraylist that are also present in the specified collection. And, all those elements that are not present in the specified collection are removed from the arraylist. The syntax of the retainAll() method is: arraylist.


1 Answers

When you use List#subList():

Returns a view of the portion of this list between the specified fromIndex, inclusive, and toIndex, exclusive. (If fromIndex and toIndex are equal, the returned list is empty.) The returned list is backed by this list, so non-structural changes in the returned list are reflected in this list, and vice-versa. The returned list supports all of the optional list operations supported by this list.

You are allowed to mutate elements within it but not change the structure of the list.

The doc further says :

The semantics of the list returned by this method become undefined if the backing list (i.e., this list) is structurally modified in any way other than via the returned list. (Structural modifications are those that change the size of this list, or otherwise perturb it in such a fashion that iterations in progress may yield incorrect results.)

The retainAll() function uses an iterator to delete the non intersecting values , this causes ConcurrentModificationException. Note what the documenation says :

Note that this exception does not always indicate that an object has been concurrently modified by a different thread. If a single thread issues a sequence of method invocations that violates the contract of an object, the object may throw this exception.

Make a copy of the List and then perform retainAll():

List<Fruits> arrNewFruits = new ArrayList<>(arrFruits.subList(0, 1));
like image 123
AllTooSir Avatar answered Oct 19 '22 20:10

AllTooSir