Инициализировать HashMap в Java

Инициализировать HashMap в Java

1. обзор

В этом руководстве мы узнаем о различных способах инициализацииHashMap in Java.

Мы будем использовать Java 8, а также Java 9.

Дальнейшее чтение:

Сравнение двух HashMaps в Java

Узнайте, как сравнить два HashMaps в Java, а также найти различия между ними

Read more

Работа с картами с использованием потоков

Узнайте, как объединить Java Maps и Streams

Read more

2. Статический инициализатор для статическогоHashMap

Мы можем инициализироватьHashMap , подозревая блок кодаstatic:

public static Map articleMapOne;
static {
    articleMapOne = new HashMap<>();
    articleMapOne.put("ar01", "Intro to Map");
    articleMapOne.put("ar02", "Some article");
}

Преимущество этого вида инициализации в том, что карта изменяема, но работает только для статики. Записи можно было добавлять и удалять по мере необходимости.

Давайте продолжим и протестируем:

@Test
public void givenStaticMap_whenUpdated_thenCorrect() {

    MapInitializer.articleMapOne.put(
      "NewArticle1", "Convert array to List");

    assertEquals(
      MapInitializer.articleMapOne.get("NewArticle1"),
      "Convert array to List");
}

Мы также можем инициализировать карту, используя синтаксис двойной скобки:

Map doubleBraceMap  = new HashMap() {{
    put("key1", "value1");
    put("key2", "value2");
}};

Обратите внимание, чтоwe must try to avoid this initialization technique as it creates an anonymous extra class at every usage, and also holds hidden references to the enclosing object и могут вызвать проблемы с утечкой памяти.

3. Использование коллекций Java

Если нам нужно создать одноэлементную неизменяемую карту с одной записью, очень полезенCollections.singletonMap() :

public static Map createSingletonMap() {
    return Collections.singletonMap("username1", "password1");
}

Обратите внимание, что карта здесь неизменна, если мы попытаемся добавить больше записей, она выдастjava.lang.UnsupportedOperationException.

Мы также можем создать неизменяемую пустую карту, используяCollections.emptyMap():

Map emptyMap = Collections.emptyMap();

4. Java 8 Way

Здесь, в этом разделе, давайте рассмотрим способы инициализации карты с использованием Java 8Stream API.

4.1. ИспользуяCollectors.toMap()

Давайте возьмемStream из двумерного массиваString и соберем их в карту:

Map map = Stream.of(new String[][] {
  { "Hello", "World" },
  { "John", "Doe" },
}).collect(Collectors.toMap(data -> data[0], data -> data[1]));

Обратите внимание, что здесь тип данных ключа и значениеMap одинаковы.

Чтобы сделать его более общим, давайте возьмем массивObjects and и выполним ту же операцию:

 Map map = Stream.of(new Object[][] {
     { "data1", 1 },
     { "data2", 2 },
 }).collect(Collectors.toMap(data -> (String) data[0], data -> (Integer) data[1]));

Здесь мы создаем карту ключа какString и значения какInteger.

4.2. Использование потокаMap.Entry

Здесь мы будем использовать экземплярыMap.Entry. . Это еще один подход, в котором у нас есть разные типы ключей и значений.

Сначала воспользуемсяSimpleEntry упрощением синтерфейсаEntry :

Map map = Stream.of(
  new AbstractMap.SimpleEntry<>("idea", 1),
  new AbstractMap.SimpleEntry<>("mobile", 2))
  .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

Теперь давайте создадим карту, используяSimpleImmutableEntry implementation:

Map map = Stream.of(
  new AbstractMap.SimpleImmutableEntry<>("idea", 1),
  new AbstractMap.SimpleImmutableEntry<>("mobile", 2))
  .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

4.3. Инициализация неизменной карты

В некоторых случаях нам нужно инициализировать неизменяемую карту. Это можно сделать, заключивCollectors.toMap() внутрьCollectors.collectingAndThen():

Map map = Stream.of(new String[][] {
    { "Hello", "World" },
    { "John", "Doe" },
}).collect(Collectors.collectingAndThen(
    Collectors.toMap(data -> data[0], data -> data[1]),
    Collections:: unmodifiableMap));

Обратите внимание, что нам следует избегать использования такой инициализации с использованиемStreams, , поскольку это может привести к огромным накладным расходам производительности и созданию большого количества объектов мусора только для инициализации карты.

5. Java 9 Way

Java 9 поставляется с различными фабричными методами в интерфейсеMap, которые упрощают создание и инициализацию неизменяемых карт.

Давайте продолжим и рассмотрим эти фабричные методы.

5.1. Map.of()с

Этот фабричный метод не имеет аргументов, одного аргумента и переменных аргументов:

Map emptyMap = Map.of();
Map singletonMap = Map.of("key1", "value");
Map map = Map.of("key1","value1", "key2", "value2");

Обратите внимание, что этот метод поддерживает не более 10 пар ключ-значение.

5.2. Map.ofEntries()

Он похож наMap.of() , но не имеет ограничений на количество пар ключ-значение:

Map map = Map.ofEntries(
  new AbstractMap.SimpleEntry("name", "John"),
  new AbstractMap.SimpleEntry("city", "budapest"),
  new AbstractMap.SimpleEntry("zip", "000000"),
  new AbstractMap.SimpleEntry("home", "1231231231")
);

Обратите внимание, что фабричные методы создают неизменяемые карты, поэтому любая мутация приведет кUnsupportedOperationException. 

Кроме того, они не допускают нулевые ключи, а также дубликаты ключей.

Теперь, если нам нужна изменяемая или растущая карта после инициализации, мы можем создать любую из реализаций интерфейсаMap и передать эти неизменяемые карты в конструктор:

Map map = new HashMap (
  Map.of("key1","value1", "key2", "value2"));
Map map2 = new HashMap (
  Map.ofEntries(
    new AbstractMap.SimpleEntry("name", "John"),
    new AbstractMap.SimpleEntry("city", "budapest")));

6. Использование гуавы

Теперь, когда мы рассмотрели способы использования ядра Java, давайте продвинемся вперед и инициализируем карту с помощью Apache Guava:

Map articles
  = ImmutableMap.of("Title", "My New Article", "Title2", "Second Article");

Это создаст неизменяемую карту и изменчивую:

Map articles
  = Maps.newHashMap(ImmutableMap.of("Title", "My New Article", "Title2", "Second Article"));

МетодImmutableMap.of() размещает аргументы var-args в форме key1, value1, key2, value2 и так далее:

ImmutableMap.of("key1", "value1", "key2", "value2");

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

В этой статье мы рассмотрели различные способы инициализацииMap, в частности, для создания пустых, одноэлементных, неизменяемых и изменяемых карт. As you can see, there’s a huge improvement in this field since Java 9.

Как всегда, исходный код примера находится в папкеGithub project. Примеры Java 9 расположеныhere и образец Guavahere.