如何在Java中初始化一个静态Map ?

方法一:静态初始化器 方法二:实例初始化器(匿名子类) 或 还有别的方法吗?

它们各自的优点和缺点是什么?

下面是一个例子来说明这两种方法:

import java.util.HashMap;
import java.util.Map;

public class Test {
    private static final Map<Integer, String> myMap = new HashMap<>();
    static {
        myMap.put(1, "one");
        myMap.put(2, "two");
    }

    private static final Map<Integer, String> myMap2 = new HashMap<>(){
        {
            put(1, "one");
            put(2, "two");
        }
    };
}

当前回答

这里有一些很好的答案,但我想再提供一个。

创建自己的静态方法来创建和初始化Map。我在一个包中有自己的CollectionUtils类,我在项目中使用各种我经常使用的实用程序,这些实用程序对我来说很容易编写,并且避免了对一些大型库的依赖。

这是我的newMap方法:

public class CollectionUtils {
    public static Map newMap(Object... keyValuePairs) {
        Map map = new HashMap();
        if ( keyValuePairs.length % 2 == 1 ) throw new IllegalArgumentException("Must have even number of arguments");
        for ( int i=0; i<keyValuePairs.length; i+=2 ) {
            map.put(keyValuePairs[i], keyValuePairs[i + 1]);
        }
        return map;
    }
}

用法:

import static CollectionUtils.newMap;
// ...
Map aMap = newMap("key1", 1.23, "key2", 2.34);
Map bMap = newMap(objKey1, objVal1, objKey2, objVal2, objKey3, objVal3);
// etc...

它不使用泛型,但您可以按自己的意愿对地图进行类型转换(只是要确保您正确地进行了类型转换!)

Map<String,Double> aMap = (Map<String,Double>)newMap("key1", 1.23, "key2", 2.34);

其他回答

如果你只需要向映射中添加一个值,你可以使用Collections.singletonMap:

Map<K, V> map = Collections.singletonMap(key, value)

在这种情况下,我绝不会创建匿名子类。静态初始化器同样有效,如果你想让映射不可修改,例如:

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);
}

地图。Java 9+中的

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

详见JEP 269。JDK 9在2017年9月全面上市。

Java 8与流:

    private static final Map<String, TemplateOpts> templates = new HashMap<>();

    static {
        Arrays.stream(new String[][]{
                {CUSTOMER_CSV, "Plantilla cliente", "csv"}
        }).forEach(f -> templates.put(f[0], new TemplateOpts(f[1], f[2])));
    }

它也可以是Object[][],用于在forEach循环中放入任何东西并将其映射

如果你可以使用字符串表示你的数据,这也是一个选项在Java 8:

static Map<Integer, String> MAP = Stream.of(
        "1=one",
        "2=two"
).collect(Collectors.toMap(k -> Integer.parseInt(k.split("=")[0]), v -> v.split("=")[1]));