2016-08-17 154 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"然后您可以使用它作为原始地图的关键。

说了这么多,我认为你建议的直接代码是最好的选择。