28

I am preparing for an OCPJP 8 exam for the next 2 months and currently I this one got my attention as I dont understand why

public class BiPredicateTest {
    public static void main(String[] args) {
        BiPredicate<List<Integer>, Integer> containsInt = List::contains;
        List<Integer> ints = java.util.Arrays.asList(1,20,20);
        ints.add(1);
        ints.add(20);
        ints.add(20);
        System.out.println(containsInt.test(ints, 20));
        
        BiConsumer<List<Integer>, Integer> listInt = BiPredicateTest::consumeMe;
        listInt.accept(ints, 15);
        
    }
    
    public static void consumeMe(List<Integer> ints, int num) {
        ints.removeIf(i -> i>num);
        ints.forEach(System.out::println);
    }
}

this clearly is going to compile OK! but when you run it you will see the exception like this

C:\Users\user\Documents>javac BiPredicateTest.java

C:\Users\user\Documents>java BiPredicateTest
true
Exception in thread "main" java.lang.UnsupportedOperationException
        at java.util.AbstractList.remove(AbstractList.java:161)
        at java.util.AbstractList$Itr.remove(AbstractList.java:374)
        at java.util.Collection.removeIf(Collection.java:415)
        at BiPredicateTest.consumeMe(BiPredicateTest.java:22)
        at BiPredicateTest.main(BiPredicateTest.java:17)

I need some help here to understand why the asList method is not working with removeIf? i assume it will return an instance of ArrayList which implements removeIf method!.

Any answer will be appreciated.

cheers!

UPDATE: April 16,2022 The error is not happening anymore even you use the java.util.Arrays.asList, what I notice is that

  • the latest java 1.8* implementation is not using internal ArrayList class anymore but the class under java.util package.
  • the List interface also has default implementation now.
mark ortiz
  • 659
  • 1
  • 6
  • 13
  • 2
    *"i assume it will return an instance of ArrayList"* Why do you assume something? When you plan to learn for a Java certificate, then you should learn to read the documentation. So don't _assume_ something, read the doc and _understand_. – Tom Mar 25 '17 at 19:44
  • @Tom thanks for the heads up you are totally right, but i felt more comfortable when others knows exactly the answer, it ADDS validation on top of my own readings. :) but thanks anyways :) – mark ortiz Mar 25 '17 at 20:15
  • The answer for that is not directly on documentation. Some times we need some help to get the problem on line code on the flow method. Thanks for the question Mark. – Guilherme Jul 20 '21 at 12:19

1 Answers1

57

java.util.Arrays.asList() produces a list from which it is impossible to remove elements, so it throws on a removal attempt.

You could wrap it with ArrayList:

List<Integer> ints = new java.util.ArrayList<>(java.util.Arrays.asList(1,20,20));

Update

Arrays.asList() returns return new ArrayList<>(a); where ArrayList is not java.util.ArrayList, but java.util.Arrays.ArrayList (internal class), which does not allow removal.

Roman Puchkovskiy
  • 11,415
  • 5
  • 36
  • 72
  • Maybe you should say that it is not that it does not work with `removeIf`, but with `add` – Kedar Mhaswade Mar 25 '17 at 18:20
  • 8
    The list returned by `Arrays.asList()` is **not** unmodifiable, it has a fixed length so you can't remove or add items, but you can change the values! – Mark Rotteveel Mar 25 '17 at 18:20
  • You are right, the answer was not accurate enough. Fixed it to tell that the produced list does not allow removal. – Roman Puchkovskiy Mar 25 '17 at 18:25
  • Oh!!! thanks @rpuch I thought ArrayList returned by the asList method is the same Package under java.util but instead it returns ArrayList under java.util.Arrays class. cheers!! :) – mark ortiz Mar 25 '17 at 18:34
  • I did a Arrays.asList on my unit test. I got the error on the real code. And the method is public. Unwittingly I saw that I have to get an immutable list and have no error if is. – Guilherme Jul 20 '21 at 12:23