【问题标题】:How to convert Map to List in Java 8如何在 Java 8 中将 Map 转换为 List
【发布时间】:2016-01-30 21:49:34
【问题描述】:

如何在 Java 8 中将 Map<String, Double> 转换为 List<Pair<String, Double>>

我写了这个实现,但是效率不高

Map<String, Double> implicitDataSum = new ConcurrentHashMap<>();
//....
List<Pair<String, Double>> mostRelevantTitles = new ArrayList<>();
implicitDataSum.entrySet()
               .stream()
               .sorted(Comparator.comparing(e -> -e.getValue()))
               .forEachOrdered(e -> mostRelevantTitles.add(new Pair<>(e.getKey(), e.getValue())));

return mostRelevantTitles;

我知道它应该可以使用.collect(Collectors.someMethod())。但我不明白该怎么做。

【问题讨论】:

    标签: java java-8 java-stream


    【解决方案1】:

    好吧,您想将Pair 元素收集到List 中。这意味着您需要将您的Stream&lt;Map.Entry&lt;String, Double&gt;&gt; 映射到Stream&lt;Pair&lt;String, Double&gt;&gt;

    这是通过map 操作完成的:

    返回一个流,该流包含将给定函数应用于该流的元素的结果。

    在这种情况下,该函数是将Map.Entry&lt;String, Double&gt; 转换为Pair&lt;String, Double&gt; 的函数。

    最后,你想把它收集到一个List,所以我们可以使用内置的toList()收集器。

    List<Pair<String, Double>> mostRelevantTitles = 
        implicitDataSum.entrySet()
                       .stream()
                       .sorted(Comparator.comparing(e -> -e.getValue()))
                       .map(e -> new Pair<>(e.getKey(), e.getValue()))
                       .collect(Collectors.toList());
    

    请注意,您可以将比较器 Comparator.comparing(e -&gt; -e.getValue()) 替换为 Map.Entry.comparingByValue(Comparator.reverseOrder())

    【讨论】:

    • 请注意,-e.getValue() 不会重新排序 NaN。前向顺序假定列表末尾有Double.NaN 值。使用一元减号,您将恢复所有 除了 NaN:它们仍将位于列表的末尾。
    • 是的,Map.Entry.comparingByValue(Comparator.reverseOrder())Collections.reverseOrder(Map.Entry.comparingByValue())。如果打算比较负值 Tagir explained the difference,则应首选 Comparator.comparingDouble 以避免重新装箱值。
    【解决方案2】:

    注意,如果你想要高效实现,你应该考虑这个:

    List<Pair<String, Double>> mostRelevantTitles = 
        implicitDataSum.entrySet()
                       .stream()
                       .map(e -> new Pair<>(e.getKey(), e.getValue()))
                       .collect(Collectors.toList());
    mostRelevantTitles.sort(Comparators.comparing(Pair::getSecond, Comparator.reverseOrder()));
    

    我假设你的 Pair 类有 getSecond getter。

    使用sorted() 流管道步骤创建中间缓冲区,将所有内容存储到该缓冲区,将其转换为数组,对该数组进行排序,然后将结果存储到ArrayList。我的方法虽然功能较少,但将数据直接存储到目标 ArrayList 中,然后就地对其进行排序,无需任何额外的复制。所以我的解决方案将花费更少的时间和中间内存。

    【讨论】:

      【解决方案3】:
          public List<TeamResult> process(final Map<String, Team> aggregatedMap) {
         return aggregatedMap.entrySet()
                             .stream()
                             .map(e -> new TeamResult(e.getKey(),e.getValue()))
                             .collect(Collectors.toList());
          }
      

      【讨论】:

        【解决方案4】:

        根据值以相反的顺序对 Map 进行排序并收集列表中的键,并且仅限制列表中的前 2 个结果

            List<String> list = map.keySet().stream()
                        .sorted((k1, k2)->map.get(k2)- map.get(k1))
                        .limit(2)
                        .collect(Collectors.toList())
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-01-23
          • 2015-03-20
          • 2019-07-31
          • 1970-01-01
          • 2018-07-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多