views:

93

answers:

2

I just came across this answer in SO where it is mentioned that the Google-collections MapMaker is awesome.I went through the documentation but couldn't really figure out where i can use it.Can any one point out some scenario's where it would be appropriate to use a MapMaker.

+1  A: 

It may help if you look at the descriptions of SoftReference and WeakReference.

SoftReference is very useful for use in caches, as they will be specifically cleared when memory gets low.

WeakReference tells the Garbage Collector that it can collect the object referenced to it as long as there are no strong references to it elsewhere. This is typically used with things that can be quickly looked up again as needed.

So, consider using MapMaker to create a ConcurrentMap with softValues for a cache, and one with weakKeys for temporary lookup tables.

Edit: softValues uses an LRU policy.

R. Bemrose
+2  A: 

Here's a quick sample of one way I've used MapMaker:

private final ConcurrentMap<Long, Foo> fooCache = new MapMaker()
    .softValues()
    .makeComputingMap(new Function<Long, Foo>() {
          public Foo apply(Long id) {
            return getFooFromServer(id);
          }
        });

 public Foo getFoo(Long id) {
   return fooCache.get(id);
 }

When get(id) is called on the map, it'll either return the Foo that is in the map for that ID or it'll retrieve it from the server, cache it, and return it. I don't have to think about that once it's set up. Plus, since I've set softValues(), the cache can't fill up and cause memory issues since the system is able to clear entries from it in response to memory needs. If a cached value is cleared from the map, though, it can just ask the server for it again the next time it needs it!

The thing is, this is just one way it can be used. The option to have the map use strong, weak or soft keys and/or values, plus the option to have entries removed after a specific amount of time, lets you do lots of things with it.

ColinD
@Collin: Ok then i guess i'll leave it open until some moderator closes it.
Emil
Should `getFoo` and `getFooFromServer` be the same function here?
Tom Tresansky
@Tom: No, because when `fooCache.get(id)` is called, the computing map's `Function` will be called if the value is not in the cache. If the `Function` called `getFoo` again, it would once again try to call `fooCache.get`. That said, the code for `getFooFromServer()` could be defined right inside the `Function` instead of as a separate method... I just used a named method to make it clear what the function does without having to write any actual fake code for calling the server.
ColinD