2012-12-21 27 views
10

这个问题是一种已经张贴在这里: How to convert Map<String, String> to Map<Long, String> using guava为什么番石榴不提供一种方法来改变地图键

我觉得CollinD的答案是合适的:

所有的番石榴的方法转化并过滤产生的结果...只有在需要使用 对象时才会应用函数/谓词。他们不创建副本。因此, 转换很容易破坏Set的要求。

比方说,例如,您有一个Map<String, String>,它包含 “1”和“01”作为关键字。它们都是截然不同的String s,所以 Map可合法地包含这两个键。但是,如果使用 Long.valueOf(String)转换它们,则它们都映射到值1。他们不再是独特的钥匙。如果您创建地图的副本并添加条目,这不会破坏任何内容,因为任何重复的 键都会覆盖该键的先前条目。然而,懒惰的 转换Map,但是,将无法执行唯一密钥 ,并因此将破坏Map的合同。

这是真实的,但实际上我不明白为什么它不这么做,因为:

  • 当关键转型发生,如果2个键“合并”,运行时异常可能是凸起,或者,我们可以通过一个标志,指示番石榴要为新计算的关键

  • 我们可以有一个Maps.transformKeys其产生的Multimap之

  • 多个可能的值(FAILFAST /故障的可能性)的任何值

有没有缺点我没有看到做这种事情?

+0

似乎更适合程序员.stackexchange.com –

回答

8

正如@CollinD所建议的,没有办法以懒惰的方式来做到这一点。要实现get,必须将所有密钥与转换函数一起转换(以确保发现任何重复项)。

因此将​​应用于Map<K,V>就出来了。

你可以安全地应用于Function<NewK,K>到地图:

V value = innerMap.get(fn.apply(newK)); 

我没有看到一个番石榴简写 - 它可能只是不够用。你可以得到类似的结果:

Function<NewK,V> newFn = Functions.compose(Functions.forMap(map), fn);