2016-08-17 153 views
0

我想在HashMap中變換鍵。該地圖有lower_underscore鍵,但預期的地圖應該有camelCase鍵。該地圖也可能具有空值。映射映射鍵的最佳方式

的straightfoward代碼要做到這一點是在這裏:

Map<String, Object> a = new HashMap<String, Object>() {{ 
     put("foo_bar", 100); 
     put("fuga_foga", null); // A value may be null. Collectors.toMap can't handle this value. 
    }}; 
    Map<String, Object> b = new HashMap<>(); 
    a.forEach((k,v) -> b.put(toCamel(k), v)); 

我想知道要做到這一點像番石榴的Maps.transformValues()或Maps.transformEntries()方法,但這些方法只是轉換值。

Collectors.toMap()也是關閉的,但是當存在空值時,此方法會拋出NullPointerException。

Map<String, Object> collect = a.entrySet().stream().collect(
      Collectors.toMap(x -> toCamel(x.getKey()), Map.Entry::getValue)); 
+1

關於'Collectors:toMap' NPE的討論http://stackoverflow.com/questions/24630963/java-8-nullpointerexception-in-collectors-tomap – Dhananjay

回答

1

如果你絕對要解決這個使用流,你可以做這樣的:

Map<String, Object> b = a.entrySet() 
    .stream() 
    .collect(HashMap::new, 
      (m, e) -> m.put(toCamel(e.getKey()), e.getValue()), 
      HashMap::putAll); 

我覺得你的問題出更容易閱讀的「傳統」的方式:

Map<String, Object> b = new HashMap<>(); 
a.forEach((k,v) -> b.put(toCamel(k), v)); 
1

這是打算作爲評論,但爲此太長了。

想要像Guava的Maps.transformValues()或Maps.transformEntries()這樣的東西沒有太多的意義,我認爲。
這些方法會返回原始地圖的視圖,並且當您使用某個鍵獲取某些值時,該值將通過您指定的某個函數進行轉換。 (我在這裏可能是錯誤的,因爲我不熟悉番石榴,但我正在根據文檔做出這些假設)

如果你想要「轉換」鍵,那麼你可以通過編寫一個wapper地圖像這樣:

public class KeyTransformingMap<K, V> implements Map { 
    private Map<K, V> original; 
    private Function<K, K> reverseTransformer; 

    public V get(Object transformedKey) { 
     K originalKey = reverseTransformer.apply((K) transformedKey); 
     return original.get(originalKey); 
    } 

    // delegate all other Map methods directly to original map (or throw UnsupportedOperationException) 
} 

在你的情況下,你有蛇的情況下密鑰的地圖,但希望駱駝鍵, 的reverseTransformer功能將採取在駝峯字符串,返回蛇的情況下字符串。
I.e reverseTransformer.apply("snakeCase")返回"snake_case"然後您可以使用它作爲原始地圖的關鍵。

說了這麼多,我認爲你建議的直接代碼是最好的選擇。