如何将Map <String,String>转换为Map <Long,String>?(选项:使用番石榴)

Pre*_*raj 19 java guava

我有一个Map<String, String>String关键无非是像"123"等我得到的数值,因为这个数值是从UI在我的JSF组件来数值.我不想更改UI组件的合同.

现在我想创建一个Map<Long, String>基于上面的内容Map,我transformMaps类中看到了一些方法但是所有方法都专注于转换值而不是键.

有没有更好的转换Map<String, String>方式Map<Long, String>

Col*_*inD 39

@Vivin的答案是正确的,但我认为解释为什么Guava没有任何方法允许你转换a的键Map(或者根本不变换它)是有用的Set.

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

比方说,例如,你有一个Map<String, String>包含"1"和"01"的键作为键.它们都是不同String的,因此Map可以合法地包含两个键.Long.valueOf(String)但是,如果使用它们进行变换,它们都会映射到该值1.它们不再是不同的关键.如果您创建地图副本并添加条目,则不会破坏任何内容,因为任何重复的密钥都将覆盖该密钥的上一个条目.Map然而,一个懒惰的转变,将无法强制执行唯一的密钥,因此将违反合同Map.


Vib*_*thi 24

您现在可以使用Java 8流,map,collect以更易读,更干净的方式执行此操作.

Map<String, String> oldMap

Map<Long, String> newMap = oldMap.entrySet().stream()
  .collect(Collectors.toMap(entry -> Long.parseLong(entry.getKey()), Map.Entry::getValue));
Run Code Online (Sandbox Code Playgroud)


Viv*_*ath 18

更新Java 8

您可以使用流来执行此操作:

Map<Long, String> newMap = oldMap.entrySet().stream()
  .collect(Collectors.toMap(e -> Long.parseLong(e.getKey()), Map.Entry::getValue));
Run Code Online (Sandbox Code Playgroud)

这假设所有键都是Longs的有效字符串表示.此外,转换时可能会发生冲突; 例如,"0""00"两个地图0L.


我认为你必须迭代地图:

Map<Long, String> newMap = new HashMap<Long, String>();
for(Map.Entry<String, String> entry : map.entrySet()) {
   newMap.put(Long.parseLong(entry.getKey()), entry.getValue());
}
Run Code Online (Sandbox Code Playgroud)

此代码假定您已清理了所有值map(因此没有无效的长值).

我希望有更好的解决方案.

编辑

CollectionUtils#transformedCollection(Collection, Transformer)在Commons Collection-Utils中遇到了这个方法,看起来它可能会做你想要的.从头开始,它只适用于实现的类Collection.

  • 这不是关于复杂性,但如果已经编写了某些东西或者可以使用番石榴的功能方法(我已经编写了函数)轻松实现,当然速度/效率相当,那么我不需要这样做. (2认同)