13

What's the best way to do null-safe contains on a Java collection?

in other words -

 if (collection != null && collection.contains(x))

?

I was hoping Apache commons-collections had something like CollectionUtils.contains(collection, x) that would simply return false if the collection was null, as there is with size(), which treats null like an empty collection.

However, it seems like there is no such thing - did I just miss it?

wrschneider
  • 17,913
  • 16
  • 96
  • 176
  • 5
    What is the problem with `collection != null && collection.contains(x)`? Simple and no external dependencies! – Abhinav Sarkar Dec 12 '12 at 16:53
  • 1
    @AbhinavSarkar:This is what I was thinking! – Cratylus Dec 12 '12 at 16:55
  • Here's a somewhat related post, by someone who didn't want to deal with checking for null all the time: http://stackoverflow.com/questions/271526/avoiding-null-statements-in-java – RonaldBarzell Dec 12 '12 at 16:55
  • Note that if `x` is null, there are bigger problems. Even if you've checked that `collection` is not null, there are some kinds of collection (such as a `TreeSet` without its own `Comparator`) for which `collection.contains(null)` will throw a `NullPointerException`, where you'd really want it to simply return `false`. I am still looking for a null-safe way to do `collection.contains(x)`, without explicitly catching this exception. – Dawood ibn Kareem Jan 14 '15 at 00:12

2 Answers2

11

You should instead be applying the Null Object Pattern here and use an empty collection, rather than a null collection. Of course, perhaps this is appropriate for your problem, but without more context it's hard to tell. In other words, I think you are solving the wrong problem -- why might collection be null in the first place?

Thorn G
  • 12,620
  • 2
  • 44
  • 56
  • In general I agree. Specific issue is that the collection is coming from `session.getAttribute` and thus may never have been set. So at least one not-null check is unavoidable - but if there were multiple such checks, yes, I could simply have a single check and replace with an empty collection. – wrschneider Dec 12 '12 at 19:52
  • In that case, consider using Guava's optional, perhaps? The problem is that still leaves you with a check for Optional.isPresent(). I think it's basically unavoidable. – Thorn G Dec 12 '12 at 20:51
0

Do it like this:

CollectionUtils.emptyIfNull(collection).contains(x)

There is also an equivalent version for SetUtils, MapUtils, ListUtils, etc.

This code is longer, so it seems to me it's mainly useful when you need a single expression for a Lambda.

Ariel
  • 25,995
  • 5
  • 59
  • 69