Java 如何初始化静态地图?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/507602/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 15:31:44  来源:igfitidea点击:

How can I initialise a static Map?

javadictionarycollectionsinitializationidiomatic

提问by dogbane

How would you initialise a static Mapin Java?

您将如何Map在 Java 中初始化静态?

Method one: static initialiser
Method two: instance initialiser (anonymous subclass) or some other method?

方法一:静态初始化
方法二:实例初始化(匿名子类)还是其他一些方法?

What are the pros and cons of each?

各自的优缺点是什么?

Here is an example illustrating the two methods:

以下是说明这两种方法的示例:

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

采纳答案by Miserable Variable

The instance initialiser is just syntactic sugar in this case, right? I don't see why you need an extra anonymous class just to initialize. And it won't work if the class being created is final.

在这种情况下,实例初始化程序只是语法糖,对吗?我不明白为什么你需要一个额外的匿名类来初始化。如果正在创建的类是最终的,它将不起作用。

You can create an immutable map using a static initialiser too:

您也可以使用静态初始化程序创建一个不可变的映射:

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

回答by Outlaw Programmer

One advantage to the second method is that you can wrap it with Collections.unmodifiableMap()to guarantee that nothing is going to update the collection later:

第二种方法的一个优点是您可以将其包装起来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!

回答by Mark Renouf

The second method could invoke protected methods if needed. This can be useful for initializing classes which are immutable after construction.

如果需要,第二种方法可以调用受保护的方法。这对于初始化构造后不可变的类很有用。

回答by eljenso

I would never create an anonymous subclass in this situation. Static initializers work equally well, if you would like to make the map unmodifiable for example:

在这种情况下,我永远不会创建匿名子类。如果您想让地图不可修改,静态初始值设定项同样可以正常工作,例如:

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

回答by Chase Seibert

I like the anonymous class syntax; it's just less code. However, one major con I have found is that you won't be able to serialize that object via remoting. You will get an exception about not being able to find the anonymous class on the remote side.

我喜欢匿名类的语法;它只是更少的代码。但是,我发现的一个主要缺点是您将无法通过远程处理序列化该对象。您将收到关于无法在远程端找到匿名类的异常。

回答by Brian Agnew

The anonymous class you're creating works well. However you should be aware that this is an innerclass and as such, it'll contain a reference to the surrounding class instance. So you'll find you can't do certain things with it (using XStreamfor one). You'll get some very strange errors.

您正在创建的匿名类运行良好。但是您应该知道这是一个内部类,因此,它将包含对周围类实例的引用。所以你会发现你不能用它做某些事情(使用XStream之一)。你会得到一些非常奇怪的错误。

Having said that, so long as you're aware then this approach is fine. I use it most of the time for initialising all sorts of collections in a concise fashion.

话虽如此,只要您知道这种方法就可以了。我大部分时间都使用它以简洁的方式初始化各种集合。

EDIT: Pointed out correctly in the comments that this is a static class. Obviously I didn't read this closely enough. However my comments dostill apply to anonymous inner classes.

编辑:在评论中正确指出这是一个静态类。显然我没有足够仔细地阅读这篇文章。不过我的意见仍然适用于匿名内部类。

回答by Gary Kephart

I've done something a bit different. Not the best, but it works for me. Maybe it could be "genericized".

我做了一些不同的事情。不是最好的,但它对我有用。也许它可以被“泛型化”。

private static final Object[][] ENTRIES =
{
  {new Integer(1), "one"},
  {new Integer(2), "two"},
};
private static final Map myMap = newMap(ENTRIES);

private static Map newMap(Object[][] entries)
{
  Map map = new HashMap();

  for (int x = 0; x < entries.length; x++)
  {
    Object[] entry = entries[x];

    map.put(entry[0], entry[1]);
  }

  return map;
}

回答by Kaarel

Maybe it's interesting to check out Google Collections, e.g. the videos that they have on their page. They provide various ways to initialize maps and sets, and provide immutable collections as well.

也许查看Google Collections很有趣,例如他们页面上的视频。它们提供了各种初始化映射和集合的方法,也提供了不可变的集合。

Update: This library is now named Guava.

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

回答by Peter ?tibrany

I would use:

我会用:

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

    private static Map<Integer, String> createMap() {
        Map<Integer, String> result = new HashMap<>();
        result.put(1, "one");
        result.put(2, "two");
        return Collections.unmodifiableMap(result);
    }
}
  1. it avoids an anonymous class, which I personally consider to be a bad style, and avoid
  2. it makes the creation of map more explicit
  3. it makes map unmodifiable
  4. as MY_MAP is constant, I would name it like constant
  1. 它避免了匿名类,我个人认为这是一种糟糕的风格,并避免
  2. 它使地图的创建更加明确
  3. 它使地图不可修改
  4. 由于 MY_MAP 是常数,我将其命名为常数

回答by Chris Noe

Java 5 provides this more compact syntax:

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

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