Can someone help me understand Guava CacheLoader?

carbotex picture carbotex · Oct 16, 2011 · Viewed 22.4k times · Source

I'm new to Google's Guava library and am interested in Guava's Caching package. Currently I have version 10.0.1 downloaded. After reviewing the documentation, the JUnit tests source code and even after searching google extensively, I still can't figure out how to use the Caching package. The documentation is very short, as if it was written for someone who has been using Guava's library not for a newbie like me. I just wish there are more real world examples on how to use Caching package propertly.

Let say I want to build a cache of 10 non expiring items with Least Recently Used (LRU) eviction method. So from the example found in the api, I build my code like the following:

Cache<String, String> mycache = CacheBuilder.newBuilder()
   .maximumSize(10)
   .build(
       new CacheLoader<String, String>() {
         public String load(String key) throws Exception {
           return something; // ?????
         }
       });

Since the CacheLoader is required, I have to include it in the build method of CacheBuilder. But I don't know how to return the proper value from mycache.

To add item to mycache, I use the following code:

mycache.asMap().put("key123", "value123");

To get item from mycache, I use this method:

mycache.get("key123")

The get method will always return whatever value I returned from CacheLoader's load method instead of getting the value from mycache. Could someone kindly tell me what I missed?

Answer

ColinD picture ColinD · Oct 16, 2011

Guava's Cache type is generally intended to be used as a computing cache. You don't usually add values to it manually. Rather, you tell it how to load the expensive to calculate value for a key by giving it a CacheLoader that contains the necessary code.

A typical example is loading a value from a database or doing an expensive calculation.

private final FooDatabase fooDatabase = ...;

private final LoadingCache<Long, Foo> cache = CacheBuilder.newBuilder()
    .maximumSize(10)
    .build(new CacheLoader<Long, Foo>() {
      public Foo load(Long id) {
        return fooDatabase.getFoo(id);
      }
    });

public Foo getFoo(long id) {
  // never need to manually put a Foo in... will be loaded from DB if needed
  return cache.getUnchecked(id);
}

Also, I tried the example you gave and mycache.get("key123") returned "value123" as expected.