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"}; |
正确的语法是什么?关于这件事我什么也没找到。这有可能吗?我正在寻找最短/最快的方法,将一些"最终/静态"值放入地图中,这些值在创建地图时永远不会更改,并且会提前知道。
- relatt:stackoverflow.com/questions/2041778/&hellip;
- 密切相关:stackoverflow.com/questions/507602/&hellip;(这两个问题都是关于用静态最终值初始化常量映射。)
- stackoverflow.com/questions/36951414/&hellip;
- 在Java 9中:TeqEdelList.COM/IMAILIZE-MAPJava9
- 如果使用apache.commons.collections,则可以使用commons.apache.org/proper/commons collections/javadocs/&hellip;
- 由于此处不再允许回答,请参阅stackoverflow.com/questions/507602/&hellip;
对于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")
); |
在上面的例子中,test和test2将是相同的,只是表达地图的方式不同。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 ;
} |
- 如果要在函数中初始化元素,这将不起作用…
- @迈克尔:是的,如果你想使用一个函数,你就不能使用非函数。但你为什么要这么做?
- 当你需要一个带有单个条目的地图时,有一个Collections.singletonMap():)
- 现在,稳定的Java 9已经发布,我更喜欢JavaDoc这个链接。而且+1因为一个更少的依赖!
- Java 9 EDCOX1 1在哪里被记录?
- @诺巴:在我帖子最后一个链接。
- "这对10个元素有效",如果我们想要11个元素呢?
- @乔洛:在这种情况下,使用其他的可能性之一。
- 应该是Map.entry,而不是entry,但工作方式不同。谢谢!
- @卡麦隆:如果你用的是static import,那么它就是entry。
- @洋基哦,谢谢,直到。下面是一些更多的信息给像我这样使用非静态导入的Eclipse默认值的人:geeksforgeks.org/static-import-java
- @扬基,你能详细描述一下"然而,匿名子类在某些情况下可能会引入不必要的行为吗?"
这是一条路。
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); |
- 它可以工作,但是它很难看,并且有用户在做之前应该理解的不可见的副作用-例如,在现场生成一个完整的匿名类。
- 是的,这就是我写的关于小心的方式,并给出了描述的链接。
- 伟大的联系。Greencoddtenthruleofprogramming链接中的引用值得一读。
- 这是一个在接口中初始化映射的可行选项(在接口中不能使用静态块)。
- 你能添加"as immutablemap.builder.put("k1","v1").put("k2","v2").build()"作为"of"方法最多限制为5对吗?
- +对于guava google.github.io/guava/releases/18.0/api/docs/com/google/com&zwnj;&8203;mon/&hellip;
- 第2016年。我不停地用谷歌搜索同一个问题,然后得出相同的答案。希望我每次都能投赞成票。
- 非常优雅!尼斯
- 我使用此方法将数据发送到FireBase数据库。如果不为每个"setValue"创建新的哈希映射,则可以获得并发访问异常。
- btw使用ImmutableMap.of给我一个unchecked assignment警告。
- 伟大的!谢谢。
- 当内部有变量时,不能使用此选项。你已经决定了
如果您允许第三方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的《用户指南》文章,了解其不可变的集合类型。
- 此外,guava还有不变的map.builder.put("k1","v1").put("k2","v2").build();
- 不可变映射与哈希映射不同,因为它会在空值上失败,而映射哈希映射则不会。
- 只是为了帮助其他可能面临这个问题的人。您必须键入builder以使其成为map,如下所示:maptest=immutablemap.builder()。put("k1","v1").put("k2","v2").build();
- 这真是太棒了!
没有直接的方式来做这件事- 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 );
}
}; |
- 简明扼要。我认为这是最好的答案。
- 为什么投票不多?这不比其他答案更好吗?我看起来很干净。有人能给我解释一下吗?因为我最后可能会用到这个。谢谢。
- 哇,棒极了。有趣的是钻石在这里不起作用。
- 不过,还有一些记忆方面的问题需要注意。blog.jooq.org/2014/12/08/&hellip;
- @AmalGovinus基本上,通过创建一个新的子类,您很难将HashMap中的类型参数编码到这个子类中。这只能在您实际提供它们的情况下才能工作。(对于新的(空)哈希映射,类型参数不相关。)
- 我喜欢它的整洁,但是它创建了不必要的匿名类,并且这里描述了这些问题:c2.com/cgi/wiki?双数据库初始化
- @你好,因为它和stackoverflow.com/a/6802512/1386911答案一样,只是格式不同。在这种情况下,为了可读性,这种扩展格式在紧凑格式之上没有附加值。
另一种方法,使用普通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"); |
- 我写了一个受你启发的答案:stackoverflow.com/questions/507602/&hellip;
- 另一种使用APACHE的解决方案,使用以前的Java版本:MaUTILLS。PUALL(新的HASMAP <字符串,String >),新对象[{"我的密钥","我的值")…