How can I initialise a static Map?

前端 未结 30 1007
慢半拍i
慢半拍i 2020-11-22 08:43

How would you initialise a static Map in Java?

Method one: static initialiser
Method two: instance initialiser (anonymous subclass) or some other m

相关标签:
30条回答
  • 2020-11-22 09:27

    With Java 8 I've come to use the following pattern:

    private static final Map<String, Integer> MAP = Stream.of(
        new AbstractMap.SimpleImmutableEntry<>("key1", 1),
        new AbstractMap.SimpleImmutableEntry<>("key2", 2)
    ).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
    

    It's not the most terse and a bit roundabout, but

    • it doesn't require anything outside of java.util
    • it's typesafe and easily accommodates different types for key and value.
    0 讨论(0)
  • 2020-11-22 09:27

    You may use StickyMap and MapEntry from Cactoos:

    private static final Map<String, String> MAP = new StickyMap<>(
      new MapEntry<>("name", "Jeffrey"),
      new MapEntry<>("age", "35")
    );
    
    0 讨论(0)
  • 2020-11-22 09:27

    Your second approach (Double Brace initialization) is thought to be an anti pattern, so I would go for the first approach.

    Another easy way to initialise a static Map is by using this utility function:

    public static <K, V> Map<K, V> mapOf(Object... keyValues) {
        Map<K, V> map = new HashMap<>(keyValues.length / 2);
    
        for (int index = 0; index < keyValues.length / 2; index++) {
            map.put((K)keyValues[index * 2], (V)keyValues[index * 2 + 1]);
        }
    
        return map;
    }
    
    Map<Integer, String> map1 = mapOf(1, "value1", 2, "value2");
    Map<String, String> map2 = mapOf("key1", "value1", "key2", "value2");
    

    Note: in Java 9 you can use Map.of

    0 讨论(0)
  • 2020-11-22 09:28

    Map.of in Java 9+

    private static final Map<Integer, String> MY_MAP = Map.of(1, "one", 2, "two");
    

    See JEP 269 for details. JDK 9 reached general availability in September 2017.

    0 讨论(0)
  • 2020-11-22 09:29

    I would never create an anonymous subclass in this situation. Static initializers work equally well, if you would like to make the map unmodifiable for example:

    private static final Map<Integer, String> MY_MAP;
    static
    {
        Map<Integer, String>tempMap = new HashMap<Integer, String>();
        tempMap.put(1, "one");
        tempMap.put(2, "two");
        MY_MAP = Collections.unmodifiableMap(tempMap);
    }
    
    0 讨论(0)
  • 2020-11-22 09:31

    Because Java does not support map literals, map instances must always be explicitly instantiated and populated.

    Fortunately, it is possible to approximate the behavior of map literals in Java using factory methods.

    For example:

    public class LiteralMapFactory {
    
        // Creates a map from a list of entries
        @SafeVarargs
        public static <K, V> Map<K, V> mapOf(Map.Entry<K, V>... entries) {
            LinkedHashMap<K, V> map = new LinkedHashMap<>();
            for (Map.Entry<K, V> entry : entries) {
                map.put(entry.getKey(), entry.getValue());
            }
            return map;
        }
        // Creates a map entry
        public static <K, V> Map.Entry<K, V> entry(K key, V value) {
            return new AbstractMap.SimpleEntry<>(key, value);
        }
    
        public static void main(String[] args) {
            System.out.println(mapOf(entry("a", 1), entry("b", 2), entry("c", 3)));
        }
    }
    

    Output:

    {a=1, b=2, c=3}

    It is a lot more convenient than creating and populating the map an element at a time.

    0 讨论(0)
提交回复
热议问题