I prefer using a static initializer to avoid generating anonymous classes (which would have no further purpose), so I'll list tips initializing with a static initializer. All listed solutions / tips are type-safe.
Note: The question doesn't say anything about making the map unmodifiable, so I will leave that out, but know that it can easily be done with Collections.unmodifiableMap(map)
.
First tip
The 1st tip is that you can make a local reference to the map and you give it a SHORT name:
private static final Map<Integer, String> myMap = new HashMap<>();
static {
final Map<Integer, String> m = myMap; // Use short name!
m.put(1, "one"); // Here referencing the local variable which is also faster!
m.put(2, "two");
m.put(3, "three");
}
Second tip
The 2nd tip is that you can create a helper method to add entries; you can also make this helper method public if you want to:
private static final Map<Integer, String> myMap2 = new HashMap<>();
static {
p(1, "one"); // Calling the helper method.
p(2, "two");
p(3, "three");
}
private static void p(Integer k, String v) {
myMap2.put(k, v);
}
The helper method here is not re-usable though because it can only add elements to myMap2
. To make it re-usable, we could make the map itself a parameter of the helper method, but then initialization code would not be any shorter.
Third tip
The 3rd tip is that you can create a re-usable builder-like helper class with the populating functionality. This is really a simple, 10-line helper class which is type-safe:
public class Test {
private static final Map<Integer, String> myMap3 = new HashMap<>();
static {
new B<>(myMap3) // Instantiating the helper class with our map
.p(1, "one")
.p(2, "two")
.p(3, "three");
}
}
class B<K, V> {
private final Map<K, V> m;
public B(Map<K, V> m) {
this.m = m;
}
public B<K, V> p(K k, V v) {
m.put(k, v);
return this; // Return this for chaining
}
}
Map.of
elseMap.ofEntries
, check stackoverflow.com/a/37384773/1216775 – akhil_mittal