1. Обзор
В этом уроке мы узнаем о различных способах инициализации HashMap в Java.
Мы будем использовать Java 8, а также Java 9.
Дальнейшее чтение:
Сравнение двух хэш-карт в Java
Работа С Картами С Использованием Потоков
2. Статический инициализатор для статической хэш-карты
Мы можем инициализировать HashMap с помощью статического блока кода:
public static MaparticleMapOne; 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"); }
Мы также можем инициализировать карту, используя синтаксис двойной скобки:
MapdoubleBraceMap = new HashMap () {{ put("key1", "value1"); put("key2", "value2"); }};
Обратите внимание, что мы должны стараться избегать этого метода инициализации, потому что он создает анонимный дополнительный класс при каждом использовании, содержит скрытые ссылки на заключающий объект и может вызвать проблемы с утечкой памяти.
3. Использование Коллекций Java
Если нам нужно создать одноэлементную неизменяемую карту с одной записью, Collections.singletonMap() становится очень полезным:
public static MapcreateSingletonMap() { return Collections.singletonMap("username1", "password1"); }
Обратите внимание, что карта здесь неизменна, и если мы попытаемся добавить больше записей, она выдаст java.lang.Исключение UnsupportedOperationException.
Мы также можем создать неизменяемую пустую карту с помощью Collections.emptyMap():
MapemptyMap = Collections.emptyMap();
4. Путь Java 8
В этом разделе давайте рассмотрим способы инициализации карты с помощью Java 8 Stream API.
4.1. Использование коллекторов.toMap()
Давайте используем Поток двумерного строкового массива и соберем их в карту:
Mapmap = Stream.of(new String[][] { { "Hello", "World" }, { "John", "Doe" }, }).collect(Collectors.toMap(data -> data[0], data -> data[1]));
Обратите внимание, что здесь тип данных ключа и значение Map одинаковы.
Чтобы сделать его более универсальным, давайте возьмем массив Объектов и выполним ту же операцию:
Mapmap = Stream.of(new Object[][] { { "data1", 1 }, { "data2", 2 }, }).collect(Collectors.toMap(data -> (String) data[0], data -> (Integer) data[1]));
В результате мы создаем карту ключа в виде Строки и значения в виде Целого числа .
4.2. Использование потока Map.Entry
Здесь мы будем использовать экземпляры Map.Entry. Это еще один подход, при котором у нас разные типы ключей и значений.
Во-первых, давайте использовать Простой ввод реализацию интерфейса Ввода :
Mapmap = Stream.of( new AbstractMap.SimpleEntry<>("idea", 1), new AbstractMap.SimpleEntry<>("mobile", 2)) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
Теперь давайте создадим карту с помощью SimpleImmutableEntry реализация:
Mapmap = 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() :
Mapmap = Stream.of(new String[][] { { "Hello", "World" }, { "John", "Doe" }, }).collect(Collectors.collectingAndThen( Collectors.toMap(data -> data[0], data -> data[1]), Collections:: unmodifiableMap));
Обратите внимание, что мы должны избегать использования такой инициализации с помощью Потоки, поскольку это может привести к огромным накладным расходам на производительность, и для инициализации карты создается множество объектов мусора.
5. Путь Java 9
Java 9 поставляется с различными заводскими методами в интерфейсе Map , которые упрощают создание и инициализацию неизменяемых карт.
Давайте продолжим и рассмотрим эти заводские методы.
5.1. Карта.()
Этот фабричный метод не принимает аргументов, один аргумент и переменные аргументы:
MapemptyMap = Map.of(); Map singletonMap = Map.of("key1", "value"); Map map = Map.of("key1","value1", "key2", "value2");
Обратите внимание, что этот метод поддерживает не более 10 пар ключ-значение.
5.2. Карта записей()
Он похож на Map.of () , но не имеет ограничений на количество пар ключ-значение:
Mapmap = Map.ofEntries( new AbstractMap.SimpleEntry ("name", "John"), new AbstractMap.SimpleEntry ("city", "budapest"), new AbstractMap.SimpleEntry ("zip", "000000"), new AbstractMap.SimpleEntry ("home", "1231231231") );
Обратите внимание, что заводские методы создают неизменяемые карты, поэтому любая мутация приведет к исключению UnsupportedOperationException.
Кроме того, они не допускают нулевых ключей или дубликатов ключей.
Теперь, если нам нужна изменяемая или растущая карта после инициализации, мы можем создать любую из реализаций интерфейса Map и передать эти неизменяемые карты в конструктор:
Mapmap = 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, давайте продолжим и инициализируем карту с помощью библиотеки Guava:
Maparticles = ImmutableMap.of("Title", "My New Article", "Title2", "Second Article");
Это позволило бы создать неизменяемую карту и создать изменяемую:
Maparticles = Maps.newHashMap(ImmutableMap.of("Title", "My New Article", "Title2", "Second Article"));
Метод ImmutableMap.of() также имеет перегруженные версии, которые могут принимать до 5 пар параметров ключ-значение. Вот как будет выглядеть пример с 2 парами параметров:
ImmutableMap.of("key1", "value1", "key2", "value2");
7. Заключение
В этой статье мы рассмотрели различные способы инициализации Map , в частности, для создания пустых, одноэлементных, неизменяемых и изменяемых карт. Как мы видим, с Java 9 в этой области произошли огромные улучшения.
Как всегда, пример исходного кода находится в проекте Github . Примеры Java 9 находятся здесь , а образец гуавы здесь .