Guava's BiMap cache capabilities?

I have a simple mapping table in a database that maps integer keys to specific values. Once I insert the values ​​into the table, they never go away. I would like to use GuavaCache

so that these keys can be looked up once and then stored in memory. Looks like Guava Cache

will let me do this easily. However, I need to match both paths, from key to value and from value to key, for example BiMap


Is there an easy way to get the BiMap

functionality using Cache

, or will I have to roll my own solution?

Is there an implementation BiMap

that allows concurrent access, or will I have to use read / write locks if I want efficient multithreaded access?


source to share

1 answer

Is there an easy way to get the BiMap functionality using the cache, or would I need to roll my own solution?

There Maps.synchronizedBiMap

, but I don't think this is a good starting point, as adding all the features Cache

is probably much more difficult than adding Bi

to Cache


It's also just syncronized rather than simultaneously.

Is there a BiMap implementation that allows concurrent access,


or do I have to use read and write locks if I want efficient multithreaded access?

I guess it depends on how much of the functionality BiMap

you need. BiMap

allows you

  • before get

    and put

    in both directions
  • to keep bijectivity either through forcePut

    or through put

    , throwing an exception on conflicts

If you are sure that conflicts will never happen, it is not that difficult. Maybe all you need is to link the two caches like I did here .

AFAIK to preserve bijectivity, you will need locks. If the recordings are not very common, then you do it quickly with one ReadWriteLock

. Otherwise....

You can try to use Striped

for maximum concurrency, but I am afraid it is too complicated as you will need to block the lane based on key and value. And also by the previous value in the case forcePut


Whenever I used BiMap

, later figured out that I really need to get something in more than two different ways (some secondary key) or I need to get more information. So I converted it to two or three cards in the class like

void put(K1 k1, K2 k2, E extraInfo) {
    MyEntry<K1, K2, E> e = new MyEntry<>(k1, k2, extraInfo);
    firstMap.put(k1, e);
    secondMap.put(k2, e);

MyEntry<K1, K2, E> getByFirstKey(K1 k1);
MyEntry<K1, K2, E> getBySecondKey(K2 k2);


This is a bit hacky but simple and maybe applies to your cache as well.



All Articles