Перейти к основному содержимому

Руководство по мультикарте Гуавы

· 3 мин. чтения

1. Обзор

В этой статье мы рассмотрим одну из реализаций Map из библиотеки Google Guava — Multimap . Это коллекция, которая сопоставляет ключи со значениями, подобно java.util.Map , но в которой каждый ключ может быть связан с несколькими значениями.

2. Зависимость от Maven

Сначала добавим зависимость:

<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
</dependency>

Последнюю версию можно найти здесь .

3. Реализация мультикарты

В случае с Guava Multimap, если мы добавим два значения для одного и того же ключа, второе значение не переопределит первое значение. Вместо этого у нас будет два значения в результирующей карте . Давайте посмотрим на тестовый пример:

String key = "a-key";
Multimap<String, String> map = ArrayListMultimap.create();

map.put(key, "firstValue");
map.put(key, "secondValue");

assertEquals(2, map.size());

Печать содержимого карты выведет:

{a-key=[firstValue, secondValue]}

Когда мы будем получать значения по ключу «a-key», в результате мы получим Collection<String> , содержащую «firstValue» и «secondValue»:

Collection<String> values = map.get(key);

При печати будут выводиться значения:

[firstValue, secondValue]

4. По сравнению со стандартной картой

Стандартная карта из пакета java.util не дает нам возможности присваивать несколько значений одному и тому же ключу. Давайте рассмотрим простой случай, когда мы помещаем два значения в Map , используя один и тот же ключ:

String key = "a-key";
Map<String, String> map = new LinkedHashMap<>();

map.put(key, "firstValue");
map.put(key, "secondValue");

assertEquals(1, map.size());

Результирующая карта имеет только один элемент ( «secondValue») из-за второй операции put() , которая переопределяет первое значение. Если мы хотим добиться того же поведения, что и с Multimap в Guava , нам нужно создать карту , которая имеет List<String> в качестве типа значения:

String key = "a-key";
Map<String, List<String>> map = new LinkedHashMap<>();

List<String> values = map.get(key);
if(values == null) {
values = new LinkedList<>();
values.add("firstValue");
values.add("secondValue");
}

map.put(key, values);

assertEquals(1, map.size());

Понятно, что пользоваться им не очень удобно. И если у нас есть такая потребность в нашем коде, тогда Multimap от Guava может быть лучшим выбором, чем java.util.Map.

Здесь следует отметить одну вещь: хотя у нас есть список, содержащий два элемента, метод size() возвращает 1. В Multimap size() возвращает фактическое количество значений, хранящихся в Map, но keySet().size () возвращает количество различных ключей.

5. Плюсы Мультикарты

Мультикарты обычно используются в местах, где в противном случае появились бы Map<K, Collection<V>> . Различия включают в себя:

  • Нет необходимости заполнять пустую коллекцию перед добавлением записи с помощью put() .
  • Метод get() никогда не возвращает null , а только пустую коллекцию (нам не нужно проверять значение null , как в контрольном примере Map<String, Collection<V>> )
  • Ключ содержится в Multimap тогда и только тогда, когда он соответствует хотя бы одному значению. Любая операция, которая приводит к тому, что ключ имеет нулевые связанные значения, приводит к удалению этого ключа из MultimapMap<String, Collection<V>>, даже если мы удаляем все значения из коллекции, мы по-прежнему сохраняем пустую коллекцию ). как значение, и это ненужные накладные расходы памяти)
  • Общее количество входных значений доступно как size()

6. Заключение

В этой статье показано, как и когда использовать Guava Multimap. Он сравнивает его со стандартным java.util.Map и показывает плюсы Guava Multimap.

Все эти примеры и фрагменты кода можно найти в проекте GitHub — это проект Maven, поэтому его легко импортировать и запускать как есть.