关于Java:在初始化时如何定义地图内容?

How to define Map contents on initialisation?

本问题已经有最佳答案,请猛点这里访问。

我只是想知道是否可以在初始化时定义映射对象的内容。

例如,可以创建一个数组,如下所示:

1
new String[] {"apples","bananas","pears"}

所以,我想知道我们是否可以为地图做些类似的事情。


您可以使用以下语法技巧:

1
2
3
4
Map<String,String> map = new HashMap<String,String>() {{
    put("x","y");
    put("a","b");
}};

不过,不是很愉快。这将创建HashMap的匿名子类,并将其填充到实例初始值设定项中。


如果您的Map在创建之后是不变的,并且您不介意添加依赖项,那么guava提供了一些很好的、流畅的语法:

1
Map<K,V> aMap = ImmutableMap.<K,V>builder().put(key0, val0).put(key1,val1).build();

如果你感觉异国情调,斯卡拉的语法与你想要的完全一样,可以与其他Java代码互操作:

1
val aMap = Map("a"->0,"b"->1)

请注意,scala编译器将根据您放入的内容推断Map泛型类型是从StringInt,尽管您也可以显式地指定它。

但是,如果这只是一次性的,我将使用基于初始值设定项的语法。Guava图书馆和Scala语言都有很多其他的推荐方法,但是学习一个全新的图书馆/语言可能太过分了。


可以使用初始值设定项块:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Foo {
   //using static initializer block
   static Map<String,String> m1 = new HashMap<String,String>();
   static {
      m1.put("x","y");
      m1.put("a","b");
   }    

   //using initializer block
   Map<String,String> m2 = new HashMap<String,String>();
   {
      m2.put("x","y");
      m2.put("a","b");
   }    

}


一些非常老套的东西……可以改进,但这只是一个方向:定义静态助手以将对象数组转换为此类型的映射:

1
2
3
4
5
6
7
8
9
10
    public static<K,V> Map<K, V> fromArray(Object[] anObjArray){
    int size = anObjArray.length;
    Map<K, V> aMap = new HashMap<K, V>();
    for (int i=0;i<=size/2;i=i+2){
        K key = (K)anObjArray[i];
        V value = (V)anObjArray[i+1];
        aMap.put(key, value);
    }
    return aMap;
}

然后您可以使用以下方法创建地图:

1
        Map<Integer, String> aMap = MapUtils.<Integer, String>fromArray(new Object[]{1,"one", 2,"two"});

不过,我个人还是愿意接受@carl提出的第二个gauva建设者建议。