Eu prefiro usar um inicializador estático para evitar a geração de classes anônimas (que não teriam mais nenhum objetivo), portanto, listarei dicas de inicialização com um inicializador estático. Todas as soluções / dicas listadas são de tipo seguro.
Nota: A pergunta não diz nada sobre como tornar o mapa inalterável, então deixarei isso de fora, mas sei que isso pode ser feito facilmente Collections.unmodifiableMap(map)
.
Primeira dica
A primeira dica é que você pode fazer uma referência local ao mapa e atribuir um nome CURTO:
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");
}
Segunda dica
A segunda dica é que você pode criar um método auxiliar para adicionar entradas; você também pode tornar público esse método auxiliar se desejar:
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);
}
O método auxiliar aqui não é reutilizável, porque apenas pode adicionar elementos myMap2
. Para torná-lo reutilizável, poderíamos tornar o mapa em si um parâmetro do método auxiliar, mas o código de inicialização não seria mais curto.
Terceira dica
A terceira dica é que você pode criar uma classe auxiliar reutilizável do tipo construtor com a funcionalidade de preenchimento. Esta é realmente uma classe auxiliar simples de 10 linhas que é segura para o tipo:
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
}
}