如何使用Google集合将List <String>转换为Map <String,String>?

osh*_*hai 51 java dictionary list guava

我有一个字符串列表,我有一个函数为列表中的每个键生成一个值.

我想用这个函数创建一个地图.我可以使用Google收藏吗?

dog*_*ane 88

使用Maps.uniqueIndex(Iterable,Function):

返回一个不可变映射,Map.values()是给定顺序的给定元素,每个键是在相应值上调用提供函数的乘积.(来自javadoc)

例:

Map<String,String> mappedRoles = Maps.uniqueIndex(yourList, new Function<String,String>() {
  public String apply(String from) {
    // do stuff here
    return result;
  }});
Run Code Online (Sandbox Code Playgroud)

  • 这个解决方案的性能如何?我想在大型对象列表中使用它超过50,000个元素.我目前使用两个单独的映射,它们存储相同的对象,但映射到不同的键.我想摆脱这些地图并使用一个列表(因为键已经是对象的字段).而且您的解决方案允许我从列表中自动生成地图.但是以什么代价? (2认同)

Col*_*inD 23

截至2012年7月26日,Guava master包含两种新方法.它们应该在14.0版本中.

Maps.asMap(Set<K>, Function<? super K, V>)(和两个重载SortedSetNavigableSet)允许查看一个Set加一个Function作为Map其中用于组中的每个键的值是将所述函数应用于该密钥的结果.结果是一个视图,因此它不会复制输入集,Map结果将随着集合的变化而变化,反之亦然.

Maps.toMap(Iterable<K>, Function<? super K, V>)采取Iterable并急切地将其转换ImmutableMap为可迭代的不同元素是键的位置,值是将函数应用于每个键的结果.


Jon*_*eet 15

编辑:肖恩的权利和我完全有可能误解了这个问题.

如果原始列表是,那么听起来您可能只能使用计算映射,通过MapMaker.makeComputingMap,并忽略输入列表.编辑:正如评论中所述,现在已经在Guava 15.0中弃用并删除了它.CacheBuilder改为看看.

另一方面,如果你要求一个与列表中不在的键对应的值,那么它也不会给你一个返回null的映射.它也不会给你换而言之,这很可能并不恰当,但它是值得考虑的,这取决于你想用它做什么.:)

我会在这里留下这个答案,除非你评论说这里的方法都不适合你,在这种情况下我会删除它.


原始答案

使用Guava,你可以很容易地做到这一点Maps.uniqueIndex:

Map<String, String> map = Maps.uniqueIndex(list, keyProjection);
Run Code Online (Sandbox Code Playgroud)

(我特意提到了Guava而不是Google集合,因为我还没有检查旧版Google集合库是否包含Maps.uniqueIndex.)


Sea*_*oyd 13

要么我误解了你,要么误解了其他海报.我知道您希望列表成为地图键,同时Maps.uniqueIndex()创建映射到您的值的键(这恰恰相反).

无论如何,有一个开放的Guava问题,它要求您提供的确切功能,我也为之前的问题实现了这样的解决方案.


小智 6

使用Guava + Lamba

 Map<String, YourCustomClass> map = Maps.uniqueIndex(YourList, YourCustomClass -> YourCustomClass.getKey());
Run Code Online (Sandbox Code Playgroud)

  • 如果lambda可用,你可以放弃guava并使用Java8流API. (3认同)
  • 除非您是针对Android &lt;7.0开发的 (2认同)