Простое использование карты со списками в качестве значения

Я использую параллельную хеш-карту следующим образом:

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

Я использую список моих настраиваемых объектов в качестве значения. Когда приложение запущено, и мне нужно сохранить какой-то объект в List для определенного ключа на карте, мне нужно сначала проверить, есть ли какое-то значение (List) для этого ключа:

FooObject foo = new Foo(...);

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

Мой вопрос: есть ли способ написать более простой код? С какой-то функцией Java 8? Я также использую гуаву и пружину в проекте, поэтому, если в этих фреймворках есть какая-то утилита, мне все равно подходит. Спасибо.

Когда вы вызываете map.get(key).add(foo);, вы создаете проблему параллелизма, потому что ваш List не синхронизирован.

Mạnh Quyết Nguyễn 03.06.2018 15:15

@ MạnhQuyếtNguyễn оу, я думал, когда я использую ConcurrentHashMap, объекты в нем будут также потокобезопасными: /

Denis Stephanov 03.06.2018 15:18

Получение / установка значений Map, а не их содержимого, является потокобезопасным.

Mạnh Quyết Nguyễn 03.06.2018 15:25

@ MạnhQuyếtNguyễn спасибо за предупреждение ... Я нашел FastArrayList commons.apache.org/proper/commons-collections/javadocs/…, как вы думаете, это хорошая альтернатива?

Denis Stephanov 03.06.2018 15:30

@DenisStephanov Я считаю, что лучший способ устранить это if-else - заменить его на map.computeIfAbsent(key, k -> new ArrayList<>()).add(foo);

jbduncan 03.06.2018 22:42

@DenisStephanov А, я только что прочитал, что вам нужен параллелизм. Тогда, возможно, мой комментарий выше не совсем уместен. :) Согласно этому комментарию Guava: github.com/google/guava/issues/135#issuecomment-306172853, использование CopyOnWriteArrayList поверх FastArrayListдолжен Apache Commons Collections будет прекрасным.

jbduncan 03.06.2018 22:45

@DenisStephanov В качестве альтернативы мне кажется, что вы пытаетесь создать одновременную мультикарту, поэтому Multimaps.synchronizedListMultimap(MultimapBuilder.hashKeys(‌​).arrayListValues().‌​build()) Guava может работать в вашем случае. :)

jbduncan 03.06.2018 22:50
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
7
56
0

Другие вопросы по теме