12

这个问题已经在这里发布了: How to convert Map<String, String> to Map<Long, String> using guava

我认为CollinD的答案是合适的:

Guava 的所有转换和过滤方法都会产生惰性结果……函数/谓词仅在需要使用对象时应用。他们不创建副本。但是,正因为如此,转换很容易破坏Set.

例如,假设您有一个Map<String, String>包含“1”和“01”作为键的。它们都是不同String的 s,因此 Map可以合法地包含两者作为键。但是,如果您使用 转换它们 Long.valueOf(String),它们都会映射到 value 1。它们不再是不同的键。如果您创建地图副本并添加条目,这不会破坏任何内容,因为任何重复的键都会覆盖该键的先前条目。但是,延迟转换Map的 将无法强制执行唯一键,因此会破坏 a 的合同Map

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

  • 当键转换发生时,如果 2 个键被“合并”,则可能会引发运行时异常,或者我们可以传递一个标志以指示 Guava 为新计算的键获取多个可能值中的任何值(故障快速/故障安全可能性)

  • 我们可以有一个 Maps.transformKeys 来生成一个 Multimap

做这些事情有我看不到的缺点吗?

4

1 回答 1

8

正如@CollinD 建议的那样,没有办法以懒惰的方式做到这一点。要实现get,您必须使用转换功能转换所有键(以确保发现任何重复项)。

所以申请Function<K,NewK>Map<K,V>不行了。

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

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

我没有看到 Guava 的简写——它可能还不够有用。您可以通过以下方式获得类似的结果:

Function<NewK,V> newFn = Functions.compose(Functions.forMap(map), fn);
于 2012-12-21T16:40:48.797 回答