在一个语句中一次向HashMap添加多个条目

use*_*184 121 java iphone android hashmap nsdictionary

我需要初始化一个常量HashMap,并希望在一行语句中执行它.像这样避免某事:

  hashMap.put("One", new Integer(1)); // adding value into HashMap
  hashMap.put("Two", new Integer(2));      
  hashMap.put("Three", new Integer(3));
Run Code Online (Sandbox Code Playgroud)

在目标C中类似于此:

[NSDictionary dictionaryWithObjectsAndKeys:
@"w",[NSNumber numberWithInt:1],
@"K",[NSNumber numberWithInt:2],
@"e",[NSNumber numberWithInt:4],
@"z",[NSNumber numberWithInt:5],
@"l",[NSNumber numberWithInt:6],
nil] 
Run Code Online (Sandbox Code Playgroud)

我没有找到任何一个例子来说明如何做这个看了这么多.

Eng*_*uad 233

你可以这样做:

Map<String, Integer> hashMap = new HashMap<String, Integer>()
{{
     put("One", 1);
     put("Two", 2);
     put("Three", 3);
}};
Run Code Online (Sandbox Code Playgroud)

  • 你不应该使用这种方法.它会为您每次使用它创建一个新类,与仅仅明显创建地图相比,它的性能要差得多.请参阅http://stackoverflow.com/questions/924285/efficiency-of-java-double-brace-initialization (23认同)
  • @ user387184是的,他们称之为"双支撑初始化器".请参阅此主题:http://stackoverflow.com/questions/924285/efficiency-of-java-double-brace-initialization (9认同)
  • @TimoTürschmann似乎如果我曾经需要这样的地图的静态初始化,它也将是静态的,每次使用它时都会消除*性能损失 - 你只需要一次惩罚.我没有看到任何其他时间,人们会想要这种初始化*没有*变量是静态的(例如,有人会在循环中使用它吗?).我可能是错的,程序员是有创造力的. (6认同)
  • 请不要使用这种反模式,它 [积极危险](http://errorprone.info/bugpattern/DoubleBraceInitialization) 并且有合理的替代方案。 (4认同)
  • 我之所以选择这个是因为它并没有解释为每次使用它时都会创建一个新类.我认为人们应该意识到这样做的权衡. (3认同)
  • 我只是将它放在我的代码中,并且在行中收到此警告/消息:“可序列化类未声明 long 类型的静态最终 serialVersionUID 字段”。我可以忽略吗?这是什么意思?谢谢 (2认同)

小智 59

您可以使用Google Guava的ImmutableMap.只要您不关心稍后修改Map(在使用此方法构造它后无法在地图上调用.put()),这就可以正常工作:

import com.google.common.collect.ImmutableMap;

// For up to five entries, use .of()
Map<String, Integer> littleMap = ImmutableMap.of(
    "One", Integer.valueOf(1),
    "Two", Integer.valueOf(2),
    "Three", Integer.valueOf(3)
);

// For more than five entries, use .builder()
Map<String, Integer> bigMap = ImmutableMap.<String, Integer>builder()
    .put("One", Integer.valueOf(1))
    .put("Two", Integer.valueOf(2))
    .put("Three", Integer.valueOf(3))
    .put("Four", Integer.valueOf(4))
    .put("Five", Integer.valueOf(5))
    .put("Six", Integer.valueOf(6))
    .build();
Run Code Online (Sandbox Code Playgroud)

另见:http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/ImmutableMap.html

一个有点相关的问题:地图中HashMap的ImmutableMap.of()变通方法?

  • 请注意`ImmutableMap`不接受`null`键或值. (4认同)

Tim*_*ann 41

从Java 9开始,可以使用Map.of(...),如下所示:

Map<String, Integer> immutableMap = Map.of("One", 1, 
                                           "Two", 2, 
                                           "Three", 3);
Run Code Online (Sandbox Code Playgroud)

这个地图是不可变的.如果您希望地图是可变的,则必须添加:

Map<String, Integer> hashMap = new HashMap<>(immutableMap);
Run Code Online (Sandbox Code Playgroud)

如果您不能使用Java 9,那么您将自己编写类似的帮助方法或使用第三方库(如Guava)为您添加该功能.

  • @vikramvi是的如果你查看[文档](https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/util/Map.html#of(K, V,K,V,K,V,K,V,K,V,K,V,K,V,K,V,K,V,K,V)) `Map.of` 最多只能完成 10 个条目,因为它相当费力 (3认同)
  • 添加 10 个条目后,它抛出奇怪的错误“无法解析方法”,这是该方法的错误吗? (2认同)

dfr*_*ser 8

Java没有地图文字,所以没有什么好方法可以完全按照你的要求去做.

如果您需要这种类型的语法,请考虑一些与Java兼容的Groovy,它允许您:

def map = [name:"Gromit", likes:"cheese", id:1234]
Run Code Online (Sandbox Code Playgroud)


Dak*_*san 7

这是一个简单的课程,可以完成你想要的

import java.util.HashMap;

public class QuickHash extends HashMap<String,String> {
    public QuickHash(String...KeyValuePairs) {
        super(KeyValuePairs.length/2);
        for(int i=0;i<KeyValuePairs.length;i+=2)
            put(KeyValuePairs[i], KeyValuePairs[i+1]);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后使用它

Map<String, String> Foo=QuickHash(
    "a", "1",
    "b", "2"
);
Run Code Online (Sandbox Code Playgroud)

这产生了 {a:1, b:2}


Sad*_*Ali 7

地图还在Java 9中添加了工厂方法.对于最多10个条目,地图具有重载构造函数,这些构造函数包含成对的键和值.例如,我们可以建立一个不同城市及其人口的地图(根据谷歌在2016年10月)如下:

Map<String, Integer> cities = Map.of("Brussels", 1_139000, "Cardiff", 341_000);
Run Code Online (Sandbox Code Playgroud)

Map的var-args情况有点困难,你需要同时拥有键和值,但在Java中,方法不能有两个var-args参数.因此,通过采用Map.Entry<K, V>对象的var-args方法并添加entry()构造它们的静态方法来处理一般情况.例如:

Map<String, Integer> cities = Map.ofEntries(
    entry("Brussels", 1139000), 
    entry("Cardiff", 341000)
);
Run Code Online (Sandbox Code Playgroud)

Java 9中的集合工厂方法