映射映射键的最佳方式
问题描述:
我想在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));
答
如果你绝对要解决这个使用流,你可以做这样的:
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));
答
这是打算作为评论,但为此太长了。
想要像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"
然后您可以使用它作为原始地图的关键。
说了这么多,我认为你建议的直接代码是最好的选择。
关于'Collectors:toMap' NPE的讨论http://*.com/questions/24630963/java-8-nullpointerexception-in-collectors-tomap – Dhananjay