HashMap的构建器

Ela*_*ich 104 java collections guava

Guava为Java类型提供了很好的工厂方法,例如Maps.newHashMap().

但是还有java Maps的构建者吗?

HashMap<String,Integer> m = Maps.BuildHashMap.
    put("a",1).
    put("b",2).
    build();
Run Code Online (Sandbox Code Playgroud)

Sea*_*oyd 159

HashMaps没有这样的东西,但您可以使用构建器创建ImmutableMap:

final Map<String, Integer> m = ImmutableMap.<String, Integer>builder().
      put("a", 1).
      put("b", 2).
      build();
Run Code Online (Sandbox Code Playgroud)

如果你需要一个可变的地图,你可以将它提供给HashMap构造函数.

final Map<String, Integer> m = Maps.newHashMap(
    ImmutableMap.<String, Integer>builder().
        put("a", 1).
        put("b", 2).
        build());
Run Code Online (Sandbox Code Playgroud)

  • `ImmutableMap`不支持`null`值.所以这种方法有局限性:你不能将`HashMap`中的值设置为`null`. (42认同)
  • sean-patrick-floyd嗯,一个实际例子:Spring的[NamedParameterJdbcTemplate](http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/jdbc/core/namedparam/NamedParameterJdbcTemplate. html)期望由参数名称键入的值的映射.假设我想使用NamedParameterJdbcTemplate将列值设置为null.我没有看到:a)代码味道如何; b)如何在这里使用空对象模式 (5认同)
  • @vitaly不能与之争辩 (2认同)
  • 使用`new HashMap` Java构造函数而不是静态`Maps.newHashMap`方法有什么问题吗? (2认同)

Joh*_*erg 43

不是一个构建器,而是使用初始化器:

Map<String, String> map = new HashMap<String, String>() {{
    put("a", "1");
    put("b", "2");
}};
Run Code Online (Sandbox Code Playgroud)

  • 那说:我仍然认为这个解决方案是邪恶的. (57认同)
  • 这是一个非常糟糕的解决方案,应该避免:http://stackoverflow.com/a/27521360/3253277 (14认同)
  • 这是一个实例初始化器,而不是静态初始化器.它在super的构造函数之后运行,但在构造函数的主体之前运行,对于类中的每个构造函数.生命周期并不是很有名,因此我避免使用这个成语. (10认同)
  • @Elazar`map.getClass()== HashMap.class`将返回false.但无论如何,这是一个愚蠢的测试.应该首选`HashMap.class.isInstance(map)`,这将返回true. (3认同)

Jak*_*nto 36

这与接受的答案类似,但在我看来有点干净:

ImmutableMap.of("key1", val1, "key2", val2, "key3", val3);
Run Code Online (Sandbox Code Playgroud)

上述方法有几种变体,它们非常适合制作静态,不变,不可变的地图.

  • 我问了一位建筑师.你只限于少数元素. (3认同)
  • 你让我在那里:) (3认同)

Psh*_*emo 10

由于Java 9 Map接口包含:

  • Map.of(k1,v1, k2,v2, ..)
  • Map.ofEntries(Map.entry(k1,v1), Map.entry(k2,v2), ..)

这些工厂方法的局限性在于:

  • 不能将nulls用作键和/或值(如果需要存储null,请查看其他答案)
  • 产生不可变的地图-如果我们需要可变的地图,我们可以使用选定的可变地图(例如HashMap)的复制构造函数,并将Map.of(..)类似的结果传递给那里

    Map<Integer, String> map = new HashMap<>( Map.of(1,"a", 2,"b", 3,"c") );
    
    Run Code Online (Sandbox Code Playgroud)

  • 请注意,Java 9 方法不允许“null”值,这可能会成为一个问题,具体取决于用例。 (2认同)

Agn*_*nes 8

一个简单的地图构建器很容易写:

public class Maps {

    public static <Q,W> MapWrapper<Q,W> map(Q q, W w) {
        return new MapWrapper<Q, W>(q, w);
    }

    public static final class MapWrapper<Q,W> {
        private final HashMap<Q,W> map;
        public MapWrapper(Q q, W w) {
            map = new HashMap<Q, W>();
            map.put(q, w);
        }
        public MapWrapper<Q,W> map(Q q, W w) {
            map.put(q, w);
            return this;
        }
        public Map<Q,W> getMap() {
            return map;
        }
    }

    public static void main(String[] args) {
        Map<String, Integer> map = Maps.map("one", 1).map("two", 2).map("three", 3).getMap();
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            System.out.println(entry.getKey() + " = " + entry.getValue());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


cul*_*mat 7

这是一个非常简单的...

public class FluentHashMap<K, V> extends java.util.HashMap<K, V> {
  public FluentHashMap<K, V> with(K key, V value) {
    put(key, value);
    return this;
  }

  public static <K, V> FluentHashMap<K, V> map(K key, V value) {
    return new FluentHashMap<K, V>().with(key, value);
  }
}
Run Code Online (Sandbox Code Playgroud)

然后

import static FluentHashMap.map;

HashMap<String, Integer> m = map("a", 1).with("b", 2);
Run Code Online (Sandbox Code Playgroud)

参见https://gist.github.com/culmat/a3bcc646fa4401641ac6eb01f3719065


Ela*_*ich 6

您可以使用:

HashMap<String,Integer> m = Maps.newHashMap(
    ImmutableMap.of("a",1,"b",2)
);
Run Code Online (Sandbox Code Playgroud)

它不是那么优雅和可读,而是工作.