1

I am using concurrent hash map like this:

private final Map<String, List<FooObject>> map = new ConcurrentHashMap<>();

I am using List of my custom objects as value. When application started and I need store some object into List for specific key in map, I need at first check, if there are some value (List) for that key:

FooObject foo = new Foo(...);

if (map.get(key) == null) {
   map.putIfAbsent(key, Lists.newArrayList(foo))
} else {
   map.get(key).add(foo);
}

My question is if there are way to write code above more simpler? With some java 8 feature? I am also using guava and spring in project, so if there some utility in that frameworks it is still fine for me. Thanks.

Denis Stephanov
  • 4,563
  • 24
  • 78
  • 174
  • 1
    When you call `map.get(key).add(foo);`, you introduce concurrency problem because your `List` is not synchronized. – Mạnh Quyết Nguyễn Jun 03 '18 at 13:15
  • @MạnhQuyếtNguyễn ou, I thought when I am using ConcurrentHashMap, objects in it will be aslo thread safe :/ – Denis Stephanov Jun 03 '18 at 13:18
  • It is threadsafe to get/set the `Map` values, not the content of the value. – Mạnh Quyết Nguyễn Jun 03 '18 at 13:25
  • @MạnhQuyếtNguyễn thank you for warning ... I found FastArrayList https://commons.apache.org/proper/commons-collections/javadocs/api-3.2.2/org/apache/commons/collections/FastArrayList.html do you think is it good alternative? – Denis Stephanov Jun 03 '18 at 13:30
  • @DenisStephanov I believe that the best way to eliminate that if-else is to replace it with `map.computeIfAbsent(key, k -> new ArrayList<>()).add(foo);` – jbduncan Jun 03 '18 at 20:42
  • @DenisStephanov Ah, I just read that you need concurrency. Then perhaps my comment above isn't so appropriate. :) According to this Guava comment: https://github.com/google/guava/issues/135#issuecomment-306172853, using `CopyOnWriteArrayList` over Apache Commons Collections' `FastArrayList` _should_ be fine. – jbduncan Jun 03 '18 at 20:45
  • 1
    @DenisStephanov Alternatively, it sounds to me like you're trying to create a concurrent multimap, so Guava's `Multimaps.synchronizedListMultimap(MultimapBuilder.hashKeys().arrayListValues().build())` may work for your case. :) – jbduncan Jun 03 '18 at 20:50

0 Answers0