2017-08-04 88 views
3

我正在寻找一个“CLEAN & Simple”初始化ConcurrentHashMap的方法。Java 8 ConcurrentHashMap初始化

与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())); 

提供所期望的最终结果,但是我觉得

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); 
} 
+1

提取您自己的方法来描述您的预期。例如:'mapOf(with(“foo”,“bar”),...,with(“key”,“value”));' –

+0

@AndrewTobilko我在寻找一个“自我记录”解决方案,像Builder模式。然后我可以添加De Duplication。一个约束是我更喜欢标准的Java解决方案。 – Hector

+0

使用'static {}'块?它不是单行的,但是通过字符数 – the8472

回答

5

直到Java的9得到释放,没有一个方便的内置地图初始化的方法,所以我会建议看第三三方库(如谷歌的番石榴):

new ConcurrentHashMap<>(com.google.common.collect.ImmutableMap.of("Key1", "Value1")); 

总之,这里的主要问题是,你正在创建的HashMap的一个实例。

Collectors.toMap来源:

return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new); 

如果你不希望使用任何外部库,走的好方法是使用the Builder pattern。下面是一个简单的例子:

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 
       ) 
     ); 
    } 

} 

与实证:

new MapBuilder().with("Key1", "Value1") 
       .with("Key2", "Value2") 
       .build(ConcurrentHashMap::new); 

要完全独立实现(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) { ... } 

} 

该调用将被改为:

new MapBuilder<>(AbstractMap.SimpleImmutableEntry::new); 

在这一点上,我们可以决定应该为条目和地图分别选择什么实现。

+0

很好的工作,我猜你的意思是entries.stream()。collect(toMap ...)成为entries.stream()。collect(Collectors.toMap ...? – Hector