关于Java:如何直接初始化HashMap(以文字的方式)?

How to directly initialize a HashMap (in a literal way)?

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

有没有初始化Java哈希图的方法?:

1
2
Map<String,String> test =
    new HashMap<String, String>{"test":"test","test":"test"};

正确的语法是什么?关于这件事我什么也没找到。这有可能吗?我正在寻找最短/最快的方法,将一些"最终/静态"值放入地图中,这些值在创建地图时永远不会更改,并且会提前知道。


对于Java版本9或更高版本:

是的,现在这是可能的。在Java 9中,添加了两个工厂方法,简化了地图的创建:

1
2
3
4
5
6
7
8
9
10
11
// this works for up to 10 elements:
Map<String, String> test1 = Map.of(
   "a","b",
   "c","d"
);

// this works for any number of elements:
Map<String, String> test2 = Map.ofEntries(
    entry("a","b"),
    entry("c","d")
);

在上面的例子中,testtest2将是相同的,只是表达地图的方式不同。Map.of方法是为地图中最多10个元素定义的,而Map.ofEntries方法没有这样的限制。

注意,在这种情况下,生成的映射将是不可变的映射。如果您希望地图是可变的,您可以再次复制它,例如使用mutableMap = new HashMap<>(Map.of("a","b"));

(另见jep 269和javadoc)

适用于Java版本8:

不,您必须手动添加所有元素。您可以在匿名子类中使用初始值设定项来缩短语法:

1
2
3
4
Map<String, String> myMap = new HashMap<>() {{
        put("a","b");
        put("c","d");
    }};

然而,匿名子类在某些情况下可能会引入不需要的行为。

使用函数进行初始化也可以这样做,但可以提高代码的可读性:

1
2
3
4
5
6
7
8
Map<String, String> myMap = createMap();

private static Map<String, String> createMap() {
    Map<String,String> myMap = new HashMap<String,String>();
    myMap.put("a","b");
    myMap.put("c","d");
    return myMap;
}


这是一条路。

1
2
3
HashMap<String, String> h = new HashMap<String, String>() {{
    put("a","b");
}};

但是,您应该小心并确保您理解上面的代码(它创建了一个继承自hashmap的新类)。因此,您应该在这里阅读更多:http://www.c2.com/cgi/wiki?双数据库初始化或者简单地使用番石榴:

1
Map<String, Integer> left = ImmutableMap.of("a", 1,"b", 2,"c", 3);


如果您允许第三方libs,您可以使用guava的不变映射来实现文字简洁:

1
Map<String, String> test = ImmutableMap.of("k1","v1","k2","v2");

这适用于最多5个键/值对,否则可以使用其生成器:

1
2
3
4
5
Map<String, String> test = ImmutableMap.<String, String>builder()
    .put("k1","v1")
    .put("k2","v2")
    ...
    .build();

< BR>

  • 注意,番石榴的iMunabLAMAP实现与Java的HasMMAP实现不同(最明显的是它是不可变的,不允许空键/值)。
  • 有关详细信息,请参阅guava的《用户指南》文章,了解其不可变的集合类型。


没有直接的方式来做这件事- Java没有地图文字(但我认为它们是针对Java 8提出的)。

有些人喜欢这样:

1
2
Map<String,String> test = new HashMap<String, String>(){{
       put("test","test"); put("test","test");}};

这将创建hashmap的匿名子类,其实例初始值设定项将这些值放入。(顺便说一下,地图不能包含相同值的两倍,您的第二次输入将覆盖第一次输入。下一个示例将使用不同的值。)

通常的方法是这样(对于局部变量):

1
2
3
Map<String,String> test = new HashMap<String, String>();
test.put("test","test");
test.put("test1","test2");

如果您的test映射是一个实例变量,请将初始化放在构造函数或实例初始值设定项中:

1
2
3
4
5
Map<String,String> test = new HashMap<String, String>();
{
    test.put("test","test");
    test.put("test1","test2");
}

如果您的test映射是一个类变量,请将初始化放在静态初始值设定项中:

1
2
3
4
5
static Map<String,String> test = new HashMap<String, String>();
static {
    test.put("test","test");
    test.put("test1","test2");
}

如果您希望您的映射永远不更改,则应该在初始化之后用Collections.unmodifiableMap(...)包装您的映射。您也可以在静态初始值设定项中执行此操作:

1
2
3
4
5
6
7
static Map<String,String> test;
{
    Map<String,String> temp = new HashMap<String, String>();
    temp.put("test","test");
    temp.put("test1","test2");
    test = Collections.unmodifiableMap(temp);
}

(我不确定你现在能不能让test决赛…试试看,在这里报告。)


1
2
3
4
5
6
7
Map<String,String> test = new HashMap<String, String>()
{
    {
        put(key1, value1);
        put(key2, value2);
    }
};


另一种方法,使用普通Java 7类和VARARGS:用这种方法创建一个类EDCOX1(9)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public static HashMap<String, String> build(String... data){
    HashMap<String, String> result = new HashMap<String, String>();

    if(data.length % 2 != 0)
        throw new IllegalArgumentException("Odd number of arguments");      

    String key = null;
    Integer step = -1;

    for(String value : data){
        step++;
        switch(step % 2){
        case 0:
            if(value == null)
                throw new IllegalArgumentException("Null key value");
            key = value;
            continue;
        case 1:            
            result.put(key, value);
            break;
        }
    }

    return result;
}

使用如下方法:

1
HashMap<String,String> data = HashMapBuilder.build("key1","value1","key2","value2");