I have simple Guava LoadingCache use case where I pass list of key objects to getAll
and implemented loadAll
to get results when not available in cache.
The problem is When cache is empty,
getAll
for collection of records returns Map of type RegularImmutableMap
.getAll
for collection of single record returns Map of type SingletonImmutableBiMap
.This eventually leads to another problem. When I try to collect map.values()
on it, RegularImmutableMap
returns a type of ImmutableList
and SingletonImmutableBiMap
returns a type of ImmutableSet
.
From user perspective is there any specific reason/advantage why getAll
method returns different types of ImmutableMap
?
Note this has nothing to do with Cache
- the LocalCache
implementation you're presumably using simply calls ImmutableMap.copyOf()
before returning the collected results.
So your underlying question is really why does ImmutableMap.of(K, V)
return an ImmutableBiMap
?
This has been the behavior since 2012 and the short answer is because ImmutableBiMap
extends ImmutableMap
, therefore there's no need to have both a SingletonImmutableMap
and SingletonImmutableBiMap
implementation.
As matoni has said, ImmutableMap.values()
returns an ImmutableCollection
, therefore you cannot rely on a particular implementation to return an ImmutableList
or an ImmutableSet
(or some other mysterious type that extends ImmutableCollection
). Not only that, you cannot rely on the existing behavior staying this way! For a brief while (from February to June) ImmutableMap
actually didn't use ImmutableBiMap
.
This means you should not expect ImmutableMap.values()
to return an ImmutableList
, and any code that does so is broken. If you need an ImmutableList
from an ImmutableCollection
use .asList()
- for most immutable collections this can return a view in O(1) time and space.