В чем разница между HashMap и HashMultimap

Я вижу много примеров мультимапов, но не понял, почему Google Gauva отличается?

Multimap<Integer, Set<String>> option4 = HashMultimap.create(); // Gauva

Map<Integer, Set<String>> opt = new HashMap<Integer, Set<String>>(); //Core Java

Оба выше ведут себя одинаково для хранения данных или разных?

Ответ 1

MultiMap<A, B> связывает ключ типа A со значением типа Collection<B> (отсюда и название MultiMap)

Map<A, B> связывает ключ типа A со значением типа B.

Таким образом, MultiMap<Integer, Set<String>> можно рассматривать как Map<Integer, Collection<Set<String>>. Это должно быть очевидно, прочитав документацию api.

Ответ 2

Разница в том, что со второй реализацией Core Java вам нужно проверить, есть ли набор перед вставкой. Guava Multimap позаботится об этом для вас.

С Core Java:

Set<String> innerSet = opt.get(key);
if (innerSet == null) {
    innerSet = new HashSet<String>();
    opt.put(key, innerSet);
}
innerSet.add(value);

С Гуавой:

opt.put(key, value);

Guava заботится о том, чтобы инициализировать отсутствующий Set для сохранения значений, заботится о любых проблемах с потоками (например, останавливает два потока от создания нового набора для того же ключа параллельно), а также предоставляет несколько полезных методов, которые вам в противном случае нужны реализовать вручную, например, получить все значения во всех Set.

Ответ 4

Вы что-то неправильно поняли. Они даже не эквивалентны:

Multimap<Integer, Set<String>> option4 = HashMultimap.create(); // Guava
Map<Integer, Set<String>> opt = new HashMap<Integer, Set<String>>(); //Core Java

В вашем примере opt4 будет отображать одиночное Integer в набор наборов строк. Точно так же, как использование Multimap, вам не нужно явно обращаться со вторым измерением. Таким образом, правильная (эквивалентная) декларация была бы такой:

SetMultimap<Integer, String> multimap = HashMultimap.create(); // Guava

и вы можете получить представление карты следующим образом:

Map<Integer, Set<String>> mapView = multimap.asMap();

Ответ 5

Прежде всего com.google.common.collect.Multimap не является java.util.Map, он находится в отдельной иерархии.

Во-вторых, вы можете использовать все операции с Map<Integer, Set<String>> которые требуется для интерфейса Multimap, но вам придется реализовать их самостоятельно, а HashMultimap предлагает готовую реализацию.