Java 8 ConcurrentHashMap初始化

Hec*_*tor 3 java dictionary concurrenthashmap java-8 java-stream

我正在寻找初始化ConcurrentHashMap的"CLEAN&Simple"方法.

使用Java 8,我有: -

private static final Map<String, String> myStreamedMap = Stream.of(
        new AbstractMap.SimpleImmutableEntry<>("Key1", "Value1"), 
        new AbstractMap.SimpleImmutableEntry<>("Key2", "Value2"), 
        new AbstractMap.SimpleImmutableEntry<>("Key3", "Value3"), 
        new AbstractMap.SimpleImmutableEntry<>("Key4", "Value4")).
        collect(Collectors.toMap((entry) -> entry.getKey(), (entry) -> entry.getValue()));
Run Code Online (Sandbox Code Playgroud)

无论如何,我提供了所需的最终结果

" new AbstractMap.SimpleImmutableEntry<>"

让人很难看到最新情况.

有什么方法可以"隐藏"这个并保持一条线?

UPDATE

想出了这个(明显的)解决方案

private static final Map<String, String> myStreamedMapWith = Stream.of(
        with("Key1", "Value1"), 
        with("Key2", "Value2"), 
        with("Key3", "Value3"), 
        with("Key4", "Value4")).
        collect(Collectors.toMap((entry) -> entry.getKey(), (entry) -> entry.getValue()));

private static AbstractMap.SimpleImmutableEntry<String, String> with(final String key, final String value) {
    return new AbstractMap.SimpleImmutableEntry<>(key, value);
}
Run Code Online (Sandbox Code Playgroud)

And*_*lko 5

在Java 9发布之前,没有方便的内置映射初始化方法,因此我建议查看第三方库(如Google的Guava):

new ConcurrentHashMap<>(com.google.common.collect.ImmutableMap.of("Key1", "Value1"));
Run Code Online (Sandbox Code Playgroud)

无论如何,这里的主要问题是你正在创建一个实例HashMap.

来自Collectors.toMap消息来源:

return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
Run Code Online (Sandbox Code Playgroud)

如果您不想使用任何外部库,那么最好的方法是使用Builder模式.这是一个简单的例子:

class MapBuilder<K, V> {

    private List<Map.Entry<K, V>> entries = new ArrayList<>();

    public MapBuilder<K, V> with(K key, V value) {
        entries.add(new AbstractMap.SimpleImmutableEntry<>(key, value));

        return this;
    }

    public Map<K, V> build(Supplier<Map<K, V>> mapSupplier) {
        return entries.stream().collect(Collectors.toMap(
                Map.Entry::getKey,
                Map.Entry::getValue,
                (k1, k2) -> k1,
                mapSupplier
                )
        );
    }

}
Run Code Online (Sandbox Code Playgroud)

它的演示:

new MapBuilder().with("Key1", "Value1")
                .with("Key2", "Value2")
                .build(ConcurrentHashMap::new);
Run Code Online (Sandbox Code Playgroud)

为了完全独立于实现(the AbstractMap.SimpleImmutableEntry),我建议引入一个构造函数,它将一个BiFunction<KEY, VALUE, Map.Entry<KEY, VALUE>>入口初始化器作为参数:

class MapBuilder<K, V> {

    private List<Map.Entry<K, V>> entries;
    private BiFunction<K, V, Map.Entry<K, V>> function;

    public MapBuilder() {
        entries = new ArrayList<>();
    }

    public MapBuilder(BiFunction<K, V, Map.Entry<K, V>> function) {
        this();
        this.function = function;
    }

    public MapBuilder<K, V> with(K key, V value) {
        entries.add(function.apply(key, value));

        return this;
    }

    public Map<K, V> build(Supplier<Map<K, V>> mapSupplier) { ... }

}
Run Code Online (Sandbox Code Playgroud)

该电话将被更改为:

new MapBuilder<>(AbstractMap.SimpleImmutableEntry::new);
Run Code Online (Sandbox Code Playgroud)

此时,我们可以决定分别为条目和地图选择哪种实现.