I need to create a static Map
which maps a given String
to an array of int
\'s.
In other words, I\'d like to define something l
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:
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});
}};
You can also use: ImmutableMap.of(key, val)
https://guava.dev/releases/23.0/api/docs/com/google/common/collect/ImmutableMap.html#of--
static Map<String, int[]> map = new HashMap<>();
The map is static, you can access it without creating an instance of the class it's defined in. I don't know what you mean with having the keys and values static as well, because it makes no sense to me.
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.
public class ExampleClass {
public final static HashMap consts = new HashMap();
static
{
constants.put("A", "The Letter A");
constants.put("B", "The Letter B");
constants.put("C", "The Letter C");
}
/* Rest of your class that needs to know the consts */
}