How to define Map contents on initialisation?
我只是想知道是否可以在初始化时定义映射对象的内容。
例如,可以创建一个数组,如下所示:
1
| new String[] {"apples", "bananas", "pears"} |
所以,我想知道我们是否可以为地图做些类似的事情。
- 密切相关:stackoverflow.com/questions/507602/…
您可以使用以下语法技巧:
1 2 3 4
| Map <String,String > map = new HashMap <String,String >() {{
put ("x", "y");
put ("a", "b");
}}; |
不过,不是很愉快。这将创建HashMap的匿名子类,并将其填充到实例初始值设定项中。
- 好把戏。不过,我会把这些内在的东西放在不同的行上,因为现在看起来很混乱。
- @当然,不管你喜欢什么款式。不过,我一直使用这种样式,每当我看到使用这种技巧时,它也使用这种样式。你习惯了。重要的是初始值设定项,这是应该关注的。
- 好的,谢谢你们!
- 嗯,这是我第一次看到这个把戏,我想这解释了困惑。
- 这是一个非常糟糕的做法:它会导致对当前对象的引用泄漏。我希望我能投反对票,但现在还不行。
- 感谢@andaratto警告-希望了解更多原因的人:这是因为新对象map包含一个引用父对象的隐式this对象。更多信息请访问:blog.jooq.org/2014/12/08/&hellip;
- builder解决方案更好,但是@andrearatto,我甚至讨厌自己建议它,但是您不能立即从泄漏的版本创建一个普通的哈希图来释放泄漏吗?new HashMap(new HashMap() {{put("x","y"); put("a","b");}});
如果您的Map在创建之后是不变的,并且您不介意添加依赖项,那么guava提供了一些很好的、流畅的语法:
1
| Map<K,V> aMap = ImmutableMap.<K,V>builder().put(key0, val0).put(key1,val1).build(); |
如果你感觉异国情调,斯卡拉的语法与你想要的完全一样,可以与其他Java代码互操作:
1
| val aMap = Map("a"->0, "b"->1) |
请注意,scala编译器将根据您放入的内容推断Map泛型类型是从String到Int,尽管您也可以显式地指定它。
但是,如果这只是一次性的,我将使用基于初始值设定项的语法。Guava图书馆和Scala语言都有很多其他的推荐方法,但是学习一个全新的图书馆/语言可能太过分了。
可以使用初始值设定项块:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class Foo {
//using static initializer block
static Map <String,String > m1 = new HashMap <String,String >();
static {
m1. put("x", "y");
m1. put("a", "b");
}
//using initializer block
Map <String,String > m2 = new HashMap <String,String >();
{
m2. put("x", "y");
m2. put("a", "b");
}
} |
- 有人曾经向我指出,使用实例初始值设定项而不是构造函数是一个坏主意,特别是因为它使异常处理更加困难。不过,静态初始值设定项很好。
- @谢尔盖:看情况。请阅读:stackoverflow.com/questions/1355810/&hellip;
- 我不会将容易出错的代码放入初始值设定项中,但对于像填充集合这样的安全操作,我看不到任何问题。
一些非常老套的东西……可以改进,但这只是一个方向:定义静态助手以将对象数组转换为此类型的映射:
1 2 3 4 5 6 7 8 9 10
| public static <K,V > Map <K, V > fromArray (Object[] anObjArray ){
int size = anObjArray. length;
Map <K, V > aMap = new HashMap <K, V >();
for (int i =0;i <=size /2;i =i +2){
K key = (K )anObjArray [i ];
V value = (V )anObjArray [i +1];
aMap. put(key, value );
}
return aMap ;
} |
然后您可以使用以下方法创建地图:
不过,我个人还是愿意接受@carl提出的第二个gauva建设者建议。