java - 如何初始化静态Map ?

  显示原文与译文双语对照的内容

如何在Java中初始化静态映射?

方法之一:静态初始值设定项
方法二:实例 initialiser ( 匿名子类) 或者其他方法?

每种方法的优缺点是什么?

下面是演示两种方法的示例:


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

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

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

时间:

实例initialiser只是在本例中的语法糖? 我不明白为什么你需要一个额外的匿名类来初始化。 如果创建的类是 final,它将不起作用。

你也可以使用静态initialiser创建不可变映射:


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

我喜欢 Guava web 方法initialising一个静态的不变映射:


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

就像你所见,它是非常简洁的( 由于 ImmutableMap 中的工厂方法方便) 。

编辑:如果你想要地图有超过 5条目,你可以不再使用 ImmutableMap.of() 。 相反,沿着以下各行尝试 ImmutableMap.builder():


static final Map<Integer, String> MY_MAP = ImmutableMap.<Integer, String>builder()
. put(1,"one")
. put(2,"two")
//... 
. put(15,"fifteen")
. build();

更多地了解不可变 Guava 收集工具的好处,看到不变集合解释 Guava 用户指南。

( 一个子集) Guava 曾经被称为谷歌收藏 。 如果你还没有在你的Java项目中使用这个库,那么我将向你推荐一个 ! Guava 迅速成为最受欢迎的和有用的免费 3rd党库java, 研究员所以用户一致。 ( 如果你是新手,那链接后面有一些优秀的学习资源。)

我将使用:


public class Test {
 private static final Map<Integer, String> MY_MAP = createMap();

 private static Map<Integer, String> createMap() {
 Map<Integer, String> result = new HashMap<Integer, String>();
 result.put(1,"one");
 result.put(2,"two");
 return Collections.unmodifiableMap(result);
 }
}

  1. 我个人认为它是一种不好的样式,避免匿名类,避免
  2. 它使得映射的创建更加明确
  3. 它使得地图不可修改
  4. 由于MY_MAP是常量,我将它的命名为常量

Java 5提供了更紧凑的语法:


static final Map<String, String> FLAVORS = new HashMap<String, String>() {{
 put("Up","Down");
 put("Charm","Strange");
 put("Top","Bottom");
}};

第二种方法的优点是,你可以用 Collections.unmodifiableMap() 包装它,以保证以后不会更新集合:


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

//later on...

 CONSTANT_MAP.put(3,"three");//going to throw an exception!

在这种情况下,我不会创建匿名子类。 静态初始化器同样可以工作,如果你想使地图无法改变的例如:


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

GS集合中,以下所有操作都可以:


import java.util.Map;

import com.gs.collections.api.map.ImmutableMap;
import com.gs.collections.api.map.MutableMap;
import com.gs.collections.impl.factory.Maps;

public class StaticMapsTest
{
 private static final Map<Integer, String> MAP =
 Maps.mutable.of(1,"one", 2,"two");

 private static final MutableMap<Integer, String> MUTABLE_MAP =
 Maps.mutable.of(1,"one", 2,"two");


 private static final MutableMap<Integer, String> UNMODIFIABLE_MAP =
 Maps.mutable.of(1,"one", 2,"two").asUnmodifiable();


 private static final MutableMap<Integer, String> SYNCHRONIZED_MAP =
 Maps.mutable.of(1,"one", 2,"two").asSynchronized();


 private static final ImmutableMap<Integer, String> IMMUTABLE_MAP =
 Maps.mutable.of(1,"one", 2,"two").toImmutable();


 private static final ImmutableMap<Integer, String> IMMUTABLE_MAP2 =
 Maps.immutable.of(1,"one", 2,"two");
}

注意:我一个开发者在gs集合

在他们page,也许我们能去看看谷歌,比如 集合的视频十分有趣,它们有。可以 它们提供了各种方法来初始化映射和集合,并提供不可变的集合。

更新:这个库现在被命名为 Guava

下面是一个 Java 8 one-line静态映射初始值设定项:


private static final Map<String, String> EXTENSION_TO_MIMETYPE =
 Arrays.stream(new String[][] {
 {"txt","text/plain" },//
 {"html","text/html" },//
 {"js","application/javascript" },//
 {"css","text/css" },//
 {"xml","application/xml" },//
 {"png","image/png" },//
 {"gif","image/gif" },//
 {"jpg","image/jpeg" },//
 {"jpeg","image/jpeg" },//
 {"svg","image/svg+xml" },//
 }).collect(Collectors.toMap(kv -> kv[0], kv -> kv[1]));


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

如果我们声明多个常数,编写的代码将静态块,很难保持在未来。 所以最好使用匿名类。


public class Test {

 public static final Map numbers = Collections.unmodifiableMap(new HashMap(2, 1.0f){
 {
 put(1,"one");
 put(2,"two");
 }
 });
}

和其他建议unmodifiableMap用于常量明智它不能被视为常数。

...