2017-08-04 91 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