javacaffeine-cache

How to use caffeine getAll()?


The title is very straightforward, I am trying to use caffeine cache for my Minecraft plugin and I can't seem to find any good examples for cache.getAll(). The documentation doesn't help either. All I see is <,>, and ?. I really think that documentation should provide examples. So all I'm asking is if someone could provide an example


Solution

  • Actually using the documentation you should be able to understand what it's expecting as arguments. The author did a very good job. If you don't, I'd suggest you to read on Java generics and understand the syntax.

    TL;DR:

    Cache<String, Integer> cache = Caffeine.newBuilder().build();
    
    cache.getAll(List.of("one", "two", "three"), keys -> {
        Map<String, Integer> result = new HashMap<>();
        keys.forEach(key -> {
            if (key.equals("one")) result.put(key, 1);
            else if (key.equals("two")) result.put(key, 2);
            else if (key.equals("three")) result.put(key, 3);
        });
        return result;
    });
    

    The example might not make much sense in terms of functionality, but it's an example.

    The long version

    The documentation has a method signature of:

    Map<K,​V> getAll​(Iterable<? extends K> keys, Function<? super Set<? extends K>,​? extends Map<? extends K,​? extends V>> mappingFunction)

    Let's break this down.

    Map<K,​V> getAll​

    The getAll method returns a Map with a key of type K and a value of type V. If your cache implementation is something like:

    Cache<String, Integer> cache = Caffeine.newBuilder().build();
    

    then K == String and V == Integer

    The first argument of that method is:

    Iterable<? extends K> keys

    Now Iterable is a JDK interface, which is implemented by pretty much all of the Collections. Check this for "known" implementing classes. The question mark actually means "any type that extends K" (where K is String in the example)

    So as a first argument we can use something like:

    List.of("one", "two")
    

    Function<? super Set<? extends K>,​? extends Map<? extends K,​? extends V>>

    That might look confusing but it isn't if you try to break it down again. Function is an interface (that declares only one method, hence functional) that declares as the first type, the type of the input and as the second type, the type of the return. More info here.

    So ? super Set<? extends K> is any type that is a superset of Set with elements of type K (aka String in the example). Why the author opted for the super keyword? Google what "PECS" is (producer extends, consumer super).

    And then ​? extends Map<? extends K,​? extends V> is as you have figured out, an implementation of Map with keys of type K and values of type V (or Integer).

    Notes

    Returns a map of the values associated with the keys, creating or retrieving those values if necessary. The returned map contains entries that were already cached, combined with the newly loaded entries; it will never contain null keys or values.

    Self explanatory but note that the returned map would have all cache values and your mappingFunction's results combined - without null keys/values

    A single request to the mappingFunction is performed for all keys which are not already present in the cache

    Your mappingFunction will be called only once, with a list of all the keys that were requested but not found in the cache.

    All entries returned by mappingFunction will be stored in the cache, over-writing any previously cached values

    Self explanatory as well, the map that the mappingFunction returns will replace or be stored in cache