11

I was looking around for some elegant solution to removing null values from a List. I came across the following post, which says I can use list.removeAll(Collections.singletonList(null));

This, however, throws an UnsupportedOperationException, which I'm assuming is because removeAll() is attempting to do some mutative operation on the immutable singleton collection. Is this correct?

If this is the case, what would be a typical use of this singletonList? To represent a collection of size 1 when you're sure you don't want to actually do anything with the collection?

Thanks in advance.

Martin
  • 830
  • 1
  • 7
  • 24

3 Answers3

17

It works like a charm:

List<String> list = new ArrayList<String>();
list.add("abc");
list.add(null);
list.add("def");
list.removeAll(Collections.singletonList(null));
System.out.println(list);  //[abc, def]

Indeed Collections.singletonList(null) is immutable (which is unfortunately hidden in Java[1]), but the exception is thrown from your list variable. Apparently it is immutable as well, like in example below:

List<String> list = Arrays.asList("abc", null, "def");
list.removeAll(Collections.singletonList(null));

This code will throw an UnsupportedOperationException. So as you can see singletonList() is useful in this case. Use it when client code expects a read-only list (it won't modify it) but you only want to pass one element in it. singletonList() is (thread-)safe (due to immutability), fast and compact.

[1] E.g. in there is a separete hierarchy for mutable and immutable collections and API can choose whether it accept this or the other (or both, as they have common base interfaces)

Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
  • This is exactly what I wanted. I was unaware that `Arrays.asList()` returns an immutable list (although I do remember reading that it was "backed by the array that is passed into it"). This can be fixed by using the constructor of `ArrayList(Collection c)`: `new ArrayList(Arrays.asList(someArray)).removeAll(Collections.singletonList(null))` – Martin Jun 26 '12 at 12:05
2

To answer your actual question :

what would be a typical use of this singletonList? To represent a collection of size 1 when you're sure you don't want to actually do anything with the collection?

The typical use is if you have one element and want to pass it to a method that accepts a List, ie

public void registerUsers(List<User> users) {...}

User currentUser = Login Manager.getCurrentUser();
registerUsers(Collections.singletonList(currentUser));

The removeAll() is a special case for this.

daniu
  • 14,137
  • 4
  • 32
  • 53
1

Has your list been protected with

Collections.unmodifiableList(list)

Because if you have protected it and try to modify it later you get that error.

mate00
  • 2,727
  • 5
  • 26
  • 34
mihaisimi
  • 1,911
  • 13
  • 15