Handle null value using Guava MapMaker/CacheBuilder

Anthony Chatellier picture Anthony Chatellier · Nov 28, 2011 · Viewed 12.3k times · Source

I try to make a cache using MapMaker/CacheBuilder but I don't understand how to properly handle null values.

 ConcurrentMap<Key, Graph> graphs = new MapMaker()
       .concurrencyLevel(4)
       .weakKeys()
       .maximumSize(10000)
       .expireAfterWrite(10, TimeUnit.MINUTES)
       .makeComputingMap(
           new Function<Key, Graph>() {
             public Graph apply(Key key) {
               return createExpensiveGraph(key);
             }
           });

If the method createExpensiveGraph returns a null value, then a NullpointerException is thrown. I don't understand why the ComputingConcurrentHashMap throws a NPE instead of just returning a null value.

How to properly handle this ? Just catch the NPE and return null instead ? Am I missing something ?

Answer

Louis Wasserman picture Louis Wasserman · Nov 28, 2011

Guava tries to force you to avoid using null wherever possible, because improper or undocumented behavior in the presence of null can cause a huge amount of confusion and bugs. I think it's definitely a good idea to avoid using nulls wherever possible, and if you can modify your code so that it doesn't use null, I strongly recommend that approach instead.

The answer to your question critically depends on what a "null" value actually means in your application. Most likely, it means that there's "no value" for this key, or "nothing there." In this case, probably your best bet is to use Optional, wrapping non-null values with Optional.of and using Optional.absent() instead of null. If you must turn that into a null or non-null value, you can use Optional.orNull().