Create static map java

Initialize Map with Values in Java

In this tutorial, we’ll learn different ways to initialize a Map with values in Java.

Using Map.of() and Map.ofEntries()

It is possible to initialize a Map with values in a single expression if you are using Java 9 or higher version using Map.of() and Map.ofEntries() method. This is shortest possible way so far.

Map.of()

Java 9 provides mutiple Map.of() overloaded methods to initialize a Map with upto 10 key-value pairs.

MapString, Integer> emptyMap = Map.of(); MapString, Integer> singletonMap = Map.of("A", 1); MapString, Integer> map = Map.of("A", 1, "B", 2, "C", 3); 
Map.ofEntries()

If you have more than 10 key-value pairs to initialize, then you should use Map.ofEntries() method. This method has no limit and you can define any number of key-value pairs.

MapString, Integer> map = Map.ofEntries(  Map.entry("A", 1),  Map.entry("B", 2),  Map.entry("C", 3),  Map.entry("D", 4),  Map.entry("E", 5),  Map.entry("F", 6),  Map.entry("G", 7),  Map.entry("H", 8),  Map.entry("I", 9),  Map.entry("J", 10),  Map.entry("K", 11),  Map.entry("L", 12) );  map.put("M", 13); // Throw UnsupportedOperationException  map.remove("A"); // Throw UnsupportedOperationException 
Mutable Map

Thing to note that both Map.of() and Map.ofEntries() return an immutable map which means that adding or removing an element in Map result into java.lang.UnsupportedOperationException exception.

You can avoid this by creating a mutable map (by copying the immutable map to new HashMap ) in this way:-

MapString, Integer> mutableEmptyMap = new HashMap<>(Map.of()); MapString, Integer> mutableSingletonMap = new HashMap<>(Map.of("A", 1)); MapString, Integer> mutableMap = new HashMap<>(Map.ofEntries(  Map.entry("A", 1),  Map.entry("B", 2),  Map.entry("C", 3),  Map.entry("D", 4),  Map.entry("E", 5),  Map.entry("F", 6),  Map.entry("G", 7),  Map.entry("H", 8),  Map.entry("I", 9),  Map.entry("J", 10),  Map.entry("K", 11),  Map.entry("L", 12) ));  mutableMap.put("M", 13); // It works!  mutableMap.remove("A"); // It works! 

Using Java Collections

Java Collections class provide methods to initialize emptyMap() , singletonMap() and unmodifiableMap() . Note that all these methods return immutable map

MapString, Integer> emptyMap = Collections.emptyMap(); MapString, Integer> singletonMap = Collections.singletonMap("A", 1);  singletonMap.put("B", 2); // Throw UnsupportedOperationException  singletonMap.remove("A"); // Throw UnsupportedOperationException  MapString, Integer> mutableMap = new HashMap<>(singletonMap); mutableMap.put("B", 2); // It works!  MapString, Integer> immutableMap = Collections.unmodifiableMap(mutableMap); immutableMap.put("B", 2); // Throw UnsupportedOperationException 

Initialize Map as an instance variable

If you initialize a Map as an instance variable, keep the initialization in a constructor or instance initializer:-

public class MyClass    MapString, Integer> instanceMap = new HashMap<>();    instanceMap.put("A", 1);  instanceMap.put("B", 2);  > > 

Initialize Map as a static variable

If you initialize a Map as a static class variable, keep the initialization in a static initializer:-

public class MyClass    static MapString, Integer> staticMap = new HashMap<>();  static  staticMap.put("A", 1);  staticMap.put("B", 2);  > > 

Using Double Brace Initialization

You can initialize map with values using Double Brace Initialization:-

MapString, Integer> map = new HashMap<>()  < put("A", 1);  put("B", 2); >>; 

In Double brace initialization > , first brace creates a new Anonymous Inner Class, the second brace declares an instance initializer block that is run when the anonymous inner class is instantiated.

This approach is not recommended as it creates an extra class at each usage. It also holds hidden references to the enclosing instance and any captured objects. This may cause memory leaks or problems with serialization.

The alternative approach for this is to create a function to initialize a map:-

// It works for all Java versions, mutable map.  MapString, Integer> map = createMap(); map.put("C", "3"); // It works!  private static MapString, String> createMap()   MapString, Integer> map = new HashMap<>();  map.put("A", 1);  map.put("B", 2);  return map; > 

Using Stream Collectors.toMap()

We can also use Java 8 Stream API to initialize a Map with values.

When both key and value are of same type (e.g. String):-

MapString, String> mutableMap1 = Stream.of(new String[][]  "A", "a">,  "B", "b">,  "C", "c"> >).collect(Collectors.toMap(p -> p[0], p -> p[1])); 

When both key and value are of different type (e.g. String and Integer):-

MapString, Integer> mutableMap2 = Stream.of(new Object[][]  "A", 1>,  "B", 2>,  "C", 3> >).collect(Collectors.toMap(p -> (String) p[0], p -> (Integer) p[1])); 

Another approach that can easily accommodate different types for key and value involves creating a stream of map entries.

MapString, Integer> mutableMap3 = Stream.of(  new AbstractMap.SimpleEntry<>("A", 1),  new AbstractMap.SimpleEntry<>("B", 2),  new AbstractMap.SimpleEntry<>("C", 3))  .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));  MapString, Integer> mutableMap4 = Stream.of(  new AbstractMap.SimpleImmutableEntry<>("A", 1),  new AbstractMap.SimpleImmutableEntry<>("B", 2),  new AbstractMap.SimpleImmutableEntry<>("C", 3))  .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); 

The only difference between SimpleEntry and SimpleImmutableEntry is that you can set the value of SimpleEntry instance once initialized whereas set value of SimpleImmutableEntry after initialization throw UnsupportedOperationException .

Note that all the maps we have initialized using streams so far are mutable map means we can add or remove elements from them. You can initialize an immutable map using streams in this way:-

 MapString, Integer> map5 = Stream.of(  new AbstractMap.SimpleEntry<>("A", 1),  new AbstractMap.SimpleEntry<>("B", 2),  new AbstractMap.SimpleEntry<>("C", 3))  .collect(Collectors.collectingAndThen(  Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue),  Collections::unmodifiableMap  )); 

Conclusion

Let’s look at the summary of all the ways to initialize a Map with values:-

  1. Using Map.of() and Map.ofEntries() – Recommended this single line expression if you use Java 9 and above
  2. Using Java Collections – Works with all Java versions. Useful to define singleton map upto Java 8
  3. Using Double Brace Initialization — Avoid Double braces initialization. Create a method instead.
  4. Initialize Map as an instance variable — Recommended to initialize instance variable
  5. Initialize Map as a static variable — Recommended to initialize static variable
  6. Using Stream Collectors.toMap() – Too many lines of code. We can use other alternatives if possible to avoid boilerplate code.

See Also

Ashish Lahoti avatar

Ashish Lahoti is a Software Engineer with 12+ years of experience in designing and developing distributed and scalable enterprise applications using modern practices. He is a technology enthusiast and has a passion for coding & blogging.

Источник

Инициализировать статическую карту в Java

В этом посте будут обсуждаться различные методы инициализации статической карты в Java.

1. Использование статического блока инициализации

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

Хорошей практикой является обеспечение того, чтобы статическая карта не изменялась позже в любой момент. Мы можем сделать это, создав неизменяемая карта. Идея состоит в том, чтобы обернуть изменяемую карту с помощью Collections.unmodifiableMaput() и создание неизменяемый вид исходной карты только для чтения.

Для создания карты с несколькими записями лучше создать типобезопасную Builder класс, как показано ниже. Затем мы можем использовать Builder put() метод, который принимает пары ключ-значение вместо карты. put() связывает ключ со значением в построенной карте.

2. Использование статического метода

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

3. Использование Java 8

Мы можем использовать поток Java 8 для создания статических карт, получая поток из статических фабричных методов, таких как Stream.of() или же Arrays.stream() и накопление входных элементов в новую карту с использованием collectors.

Например, для инициализации карты с разными типами ключа и значения Map , мы можем сделать что-то вроде:

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

4. Использование Java 9

В Java 9 очень удобно создавать экземпляры карты, предоставляя статический фабричный метод. of() на Map интерфейс, который может создать компактный немодифицируемый экземпляр Map. Например,

Обратите внимание, что Map.of() может поддерживать до 10 пар ключ-значение. Не существует перегрузки var-args Map.of() , который может обрабатывать любое количество отображений. Чтобы создать карту с произвольным количеством записей, мы можем использовать Map.ofEntries(Map.Entry…) .Он включает в себя перегрузку varargs, поэтому нет фиксированного ограничения на размер карты. Этот подход требует, чтобы каждая пара ключ-значение была упакована. Для упаковки ключей и значений мы можем использовать Map.Entry entry(K k, V v) .

Источник

Читайте также:  Ссылки
Оцените статью