matrix
matrix

Reputation: 349

How can I test whether a Java collection supports the add operation?

In Java, whether a Collection support add depends on the concrete class. Say I have code like:

List<String> otherNames = getOthers();
names.add(myName);

The second line will raise UnsupportedOperationException if the underlying List don't support this, one common example is Collections.emptyList().

Of course, we can create a new list to hold the content, but I wonder is there is way to test the list?

Upvotes: 2

Views: 196

Answers (2)

Michael
Michael

Reputation: 44110

If you want to make sure it's mutable, you can always just defensively copy the list.

List<String> otherNames = new ArrayList<>(getOthers());
names.add(myName);

If your lists are really big, or are part of a tight loop, then you could write a method which checks the type of the list before committing to a copy, so that you don't copy an already mutable list unnecessarily.

static <T> List<T> copyIfMaybeImmutable(List<T> list) {
    //expand condition as required, e.g. CopyOnWriteArrayList
    if (!(otherNames instanceof ArrayList) && !(otherNames instanceof LinkedList)) {
        return new ArrayList<>(list);
    }
    return list;
}

(It's not possible to be comprehensive, since many methods will use anonymous or private List implementations, but there is still performance to be gained by supporting the common cases)

Use like

List<String> otherNames = copyIfMaybeImmutable(getOthers());

Upvotes: 1

Always Learning
Always Learning

Reputation: 5581

The implementation of add exists. It's just that its implementation throws the exception. That means the only way to know is to try and catch that exception. The implementation of EmptyList.add is this:

public void add(E var1) {
  throw new UnsupportedOperationException();
}

Using reflection to see if an add method exists will not tell you what you want to know because it's a perfectly valid method. Instead you need to call it and catch the exception like this:

try {
  otherNames.add(myName);
} catch (UnsupportedOperationException e) {
  // whatever you want in this case (create a copy into a Vector, etc)
  overflowList.add(myName);
}

For example you could have a Vector (called overflowList in my example) that you add any things you couldn't add to the actual list and deal with them at the end.

Upvotes: 2

Related Questions