How to create a static Map of String -> Array

You don't need to separate declaration and initialization. If you know how, it can all be done in one line!

// assumes your code declaring the constants ONE, FRED_TEXT etc is before this line
private static final Map<String, int[]> myMap = Collections.unmodifiableMap(
    new HashMap<String, int[]>() {{
        put(FRED_TEXT, new int[] {ONE, TWO, FOUR});
        put(DAVE_TEXT, new int[] {TWO, THREE});
    }});

What we have here is an anonymous class with an initialization block, which is a block of code that executes on construction after constructor, which we've used here to load the map.

This syntax/construct is sometimes erroneously called "double brace initialization" - I suppose because there's two adjacent braces - but there's actually no such thing.

The two cool things about this are:

  • it marries the declaration with the contents, and
  • because the initialization is in-line, you can also make an in-line call to Collections.unmodifiableMap(), resulting in a neat one-line declaration, initialization and conversion to unmodifiable.

If you don't need/want the map to be unmodifiable, leave out that call:

private static final Map<String, int[]> myMap = new HashMap<String, int[]>() {{
    put(FRED_TEXT, new int[] {ONE, TWO, FOUR});
    put(DAVE_TEXT, new int[] {TWO, THREE});
}};

For the sake of completeness as this is the first result in google for 'java static define map' In Java 8 you can now do this.

Collections.unmodifiableMap(Stream.of(
            new SimpleEntry<>("a", new int[]{1,2,3}),
            new SimpleEntry<>("b", new int[]{1,2,3}),
            new SimpleEntry<>("c", new int[]{1,2,3}))
            .collect(Collectors.toMap((e) -> e.getKey(), (e) -> e.getValue())));

This nice part with this is that we aren't creating anonymous classes anymore with the double brace syntax ({{ }})

We can then extend this with some code to clean up the pattern like this guy did here http://minborgsjavapot.blogspot.ca/2014/12/java-8-initializing-maps-in-smartest-way.html

public static <K, V> Map.Entry<K, V> entry(K key, V value) {
    return new AbstractMap.SimpleEntry<>(key, value);
}

public static <K, U> Collector<Map.Entry<K, U>, ?, Map<K, U>> entriesToMap() {
    return Collectors.toMap((e) -> e.getKey(), (e) -> e.getValue());
}

public static <K, U> Collector<Map.Entry<K, U>, ?, ConcurrentMap<K, U>> entriesToConcurrentMap() {
    return Collectors.toConcurrentMap((e) -> e.getKey(), (e) -> e.getValue());
}

final result

Collections.unmodifiableMap(Stream.of(
            entry("a", new int[]{1,2,3}),
            entry("b", new int[]{1,2,3}),
            entry("c", new int[]{1,2,3}))
            .collect(entriesToMap()));

which would give us a Concurrent Unmodifiable Map.


You need to declare and initialize your static map separately.

Here is the declaration piece:

private static final Map<String,int[]> MyMap;

Here is the initialization piece:

static {
    Map<String,int[]> tmpMap = new HashMap<String,int[]>();
    tmpMap.put("fred", new int[] {1,2,5,8});
    tmpMap.put("dave", new int[] {5,6,8,10,11});
    tmpMap.put("bart", new int[] {7,22,10010});
    MyMap = Collections.unmodifiableMap(tmpMap);
}

Unfortunately, arrays are always writable in Java. You wouldn't be able to assign MyMap, but you would be able to add or remove values from other parts of your program that accesses the map.

Tags:

Java

Static

Map