【问题标题】:How to transform List<String> to Map<String,String> with Google collections?如何使用 Google 集合将 List<String> 转换为 Map<String,String>?
【发布时间】:2011-06-27 14:12:31
【问题描述】:

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

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

【问题讨论】:

  • 我假设您知道这一点,但如果函数生成的值对于原始列表中的任何两个元素可能相同,则您需要使用 Multimaps.index 生成一个 Multimap可以为同一个键存储多个值。

标签: java list dictionary guava


【解决方案1】:

使用Maps.uniqueIndex(Iterable, Function)

返回一个不可变的映射, Map.values() 是给定的元素 给定的顺序,每个键是 调用提供的产品 函数对应的值。(from javadoc)

例子:

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

【讨论】:

  • 这个解决方案的性能如何?我想将它用于大型对象列表中的 50,000 多个元素。我目前使用两个单独的映射,它们存储相同的对象,但映射到不同的键。我想摆脱这些地图并使用一个列表(因为键已经是对象的字段)。您的解决方案允许我从列表中自动生成地图。但代价是什么?
  • @m_pGladiator 我知道你的问题很老,但答案可能会让其他人感兴趣......我会说 Guava 方法的提供更多是为了方便/可读性,而不是性能。如果您有疑问,请坚持手动制作循环。或者使用像 Caliper 这样的工具来衡量各自的表现。
  • OP 说他们有“一个 [function] 为列表中的每个键生成值”。 Maps.uniqueIndex 为列表中的每个值生成键,这与 OP 要求的相反。因此这个答案和 Sean 的答案是不正确的,而 ColinD 的答案是。
【解决方案2】:

截至 2012 年 7 月 26 日,Guava master 包含两种新方法来执行此操作。它们应该在 14.0 版中。

Maps.asMap(Set&lt;K&gt;, Function&lt;? super K, V&gt;)(以及SortedSetNavigableSet 的两个重载)允许您将Set 加上Function 作为Map 查看,其中集合中每个键的值是将该功能应用于该键。结果是一个视图,因此它不会复制输入集,Map 结果会随着集的变化而变化,反之亦然。

Maps.toMap(Iterable&lt;K&gt;, Function&lt;? super K, V&gt;) 接受 Iterable 并急切地将其转换为 ImmutableMap,其中可迭代的不同元素是键,值是将函数应用于每个键的结果。

【讨论】:

    【解决方案3】:

    编辑:肖恩完全有可能是对的,我误解了这个问题。

    如果原始列表是 keys,那么听起来您可以通过 MapMaker.makeComputingMap 使用计算映射,而忽略输入列表开始。 编辑:如 cmets 中所述,现在已在 Guava 15.0 中弃用和删除。请查看 CacheBuilder

    另一方面,如果您要求它提供与不在列表中的键相对应的值,这也不会为您提供返回 null 的映射。它也不会给你 换句话说,这可能是合适的,但值得考虑,这取决于你想用它做什么。 :)

    我将把这个答案留在这里,除非你评论说这里的两种方法都没有对你有用,在这种情况下我会删除它。


    原答案

    使用Guava,您可以通过Maps.uniqueIndex轻松做到这一点:

    Map<String, String> map = Maps.uniqueIndex(list, keyProjection);
    

    (我特别提到了 Guava,而不是 Google 集合,因为我没有检查旧的 Google 集合存储库是否包含 Maps.uniqueIndex。)

    【讨论】:

    • makeComputingMap 已弃用,并计划很快删除。 code.google.com/p/guava-libraries/wiki/MapMakerMigration
    • @ripper234:谢谢,已添加到 CacheBuilder 的链接。
    • 我曾考虑在我的原始评论中添加一个链接,但从 CacheBuilder 中获取地图是否简单?
    【解决方案4】:

    要么我误解了你,要么其他海报有。我了解您希望您的列表成为映射键,而 Maps.uniqueIndex() 创建键以映射到您的值(恰恰相反)。

    无论如何,有一个open Guava issue 请求您请求的确切功能,我还有一个implemented such a solution 用于上一个问题。

    【讨论】:

    • 是的,我想你可能是对的。我已经编辑了我的答案以提及计算地图,以防适合 OP,但我已经准备好完全删除答案。
    【解决方案5】:

    使用 Guava + Lambda

     Map<String, YourCustomClass> map = Maps.uniqueIndex(YourList, YourCustomClass -> YourCustomClass.getKey());
    

    【讨论】:

    • 如果 lambda 可用,您可以直接删除 guava 并使用 Java8 流 API。
    • 除非你是为 Android
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-21
    • 2021-12-21
    • 1970-01-01
    • 2015-11-21
    • 2020-04-01
    • 1970-01-01
    • 2018-09-06
    相关资源
    最近更新 更多