想象一下以下场景。您有一组已经可访问和已知的值。出于某些原因,您必须将它们放入HashMap中。
代码示例:
String a = "a";
Strinb b = "b";
...
HashMap map = new HashMap(5);
map.put("a", a);
map.put("b", b);
...
真的有必要这样做吗?我无法相信没有一个构造函数可以让你从头开始输入你的价值观。
我正在谈论这样的事情:
HashMap map = new HashMap(<"a", a>, <"b", b>, ...);
甚至是这样的事情:
HashMap map = new HashMap(5);
HashMap.putBunchOfStuff("a", a, "b", b, ...);
编辑:我的目的是询问是否有方法但更重要的是,如果答案是&#34; no&#34;,为什么没有这样的构造函数/方法。
答案 0 :(得分:15)
不幸的是,集合文字在Java 7(和Java 8)中是proposal for Project Coin,但是它从未进入最终产品,也就是说不是Java的一个特色。
这个命题就是这个
Here’s how it would look with map literals:
final Map<Integer, String> platonicSolids = {
4 : "tetrahedron",
6 : "cube",
8 : "octahedron",
12 : "dodecahedron",
20 : "icosahedron"
};
Here is the empty map literal, which has a slightly irregular syntax to make
it differ from the empty set:
Map<String, Integer> noJokeHere = { : };
但它永远不会发生,所以不幸的是,它不起作用。因此,除非你自己编写自己的魔法建造者或花哨的lambda,如on this site of Per-Åke Minborg,否则你自己就可以了。但是,该站点的以下内容应该可以使用(在Java 8中)。
//copy paste from linked site
Map<Integer, String> map = Stream.of(
new SimpleEntry<>(0, "zero"),
new SimpleEntry<>(1, "one"),
//...
new SimpleEntry<>(11, "eleven"),
new SimpleEntry<>(12, "twelve"))
.collect(Collectors.toMap((e) -> e.getKey(), (e) -> e.getValue()));
简化版,也来自site:
//copy paste from linked site
public static <K, V> Map.Entry<K, V> entry(K key, V value) {
return new AbstractMap.SimpleEntry<>(key, value);
}
public static <K, U> Collector<Map.Entry<K, U>, ?, Map<K, U>> entriesToMap() {
return Collectors.toMap((e) -> e.getKey(), (e) -> e.getValue());
}
Map<Integer, String> map = Stream.of(
entry(0, "zero"),
//...
entry(12, "twelve"))
.collect(entriesToMap());
由于these points:,未引入集合文字
&#34;简单&#34;此功能的版本(仅限集,列表,地图)不是 非常满意或受欢迎; &#34;可扩展&#34;这个功能的版本是 开放式,凌乱,几乎保证超越其设计 预算;
基于库的版本为我们提供了1%的优惠 成本,其中X>&gt; 1;
价值类型即将到来,&#34;此功能的外观如何&#34; 在价值类型的世界中,可能与世界完全不同 没有,表明尝试做这项工作会有问题 在值类型之前;
我们最好关注语言设计带宽 解决更多基于图书馆的基础问题 版本(包括:更高效的varargs,数组常量) 常量池,不可变数组,以及对缓存(和回收)的支持 在压力下)中间不可变结果)。
答案 1 :(得分:1)
默认情况下没有这样的构造函数 - 你可以在实例化时使用双括号成语yum install gcc
yum install cmake
yum install ruby-devel
地图中的所有值,但这仍然需要多次put调用:
put
实际上,您通常需要将大块数据放入可从流或其他集合访问的地图中,因此在此实例中循环多个Map<String,String> map = new HashMap<>() {{
put("a", "val1");
put("b", "val2");
//etc.
}};
调用很简单。
Guava在put
上有一个putAll()
,使您可以在实例化之前执行与此类似的操作。其他外部库可能有其他类似的行为,但事实是你不得不求助于使用外部库。
答案 2 :(得分:1)
可以使用varargs创建一个漂亮的实用工具方法来创建地图。
示例:
@SuppressWarnings("unchecked")
public static <K, V> HashMap<K, V> newMap(Object... elems) {
HashMap<K, V> m = new HashMap<K, V>();
for (int i = 0; i < elems.length; i += 2) {
m.put((K) elems[i], (V) elems[i + 1]);
}
return m;
}
Map<String, Integer> m = newMap("k1", 1, "k2", 2);
注意:这不是类型安全的,如果您在使用时出错,可能会导致地图中包含错误类型的对象,并将ClassCastException
投放到意外的位置。这称为heap pollution。示例:
Map<String, Integer> m = newMap("k1", 1, "k2", "2");
int s = m.get("k2"); // ClassCastException!
答案 3 :(得分:0)
你可以使用类似的东西:
HashMap<String, String> map = new HashMap<String, String>(5){{
put("a", "a");
put("b", "b");
}};
但我不知道你是否可以使用局部变量a和b。