Java HashMap - 是否有必要为每个集合使用.put()?

时间:2015-05-06 14:00:22

标签: java hashmap

想象一下以下场景。您有一组已经可访问和已知的值。出于某些原因,您必须将它们放入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;,为什么没有这样的构造函数/方法。

4 个答案:

答案 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,数组常量) 常量池,不可变数组,以及对缓存(和回收)的支持 在压力下)中间不可变结果)。

By Brian Goetz from Oracle

答案 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。