1

I am trying to work with intersections in java. If I have the following, i just want an arraylist with nothing in it because the intersection gives me zero.

List<String> coll1 = Arrays.asList(["A"]);
List<String> coll2 = Arrays.asList(["B","C"]);

coll1.retainAll(coll2);

However retainAll throws this exception :

java.lang.UnsupportedOperationException
    at java.util.AbstractList.remove(AbstractList.java:161)
    at java.util.AbstractList$Itr.remove(AbstractList.java:374)
    at java.util.AbstractCollection.retainAll(AbstractCollection.java:410)

If I convert the lists to sets, then I get a set which is empty if I call retainAll :

Set<String> set1 = new HashSet<String>(coll1);
Set<String> set2 = new HashSet<String>(coll2);

set1.retainAll(set2); //gives me an empty set, which is good!

Why does ArrayList have a problem with empty intersections?

Oliver Watkins
  • 12,575
  • 33
  • 119
  • 225

2 Answers2

6

This is because Arrays.asList creates an immutable list so when you call retainAll which tries to remove entries from the list it complains.

The solution is to create a new ArrayList copy of it.

public void test(String[] args) {
    List<String> coll1 = new ArrayList<>(Arrays.asList("A"));
    List<String> coll2 = new ArrayList<>(Arrays.asList("B","C"));
    coll1.retainAll(coll2);
    System.out.println(coll1);
}

prints:

[]

OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213
  • 1
    It complains specifically because the `remove` operation is unsupported in an immutable list, and `retainAll` calls `remove` on the iterator. – vikingsteve Apr 13 '18 at 09:44
2

In your code, and explain in your answer, you are not using explicitly an ArrayList but an AbstractList. And as explain in the doc

Throws: UnsupportedOperationException - if the retainAll operation is not supported by this collection

As you do not declare explicitly an ArrayList, you are not using an ArrayList but an AbstractList that has not implemented retainAll, So it throws you this Exception.

Declare your List as ArrayList and it should be okay

List<String> list1 = new ArrayList<String>();
vincrichaud
  • 2,218
  • 17
  • 34