如何在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())
。但我不明白该怎么做。
答案 0 :(得分:19)
嗯,您想要将Pair
个元素收集到List
中。这意味着您需要将Stream<Map.Entry<String, Double>>
映射到Stream<Pair<String, Double>>
。
这是通过map
操作完成的:
返回一个流,该流包含将给定函数应用于此流的元素的结果。
在这种情况下,该函数将是将Map.Entry<String, Double>
转换为Pair<String, Double>
的函数。
最后,您希望将其收集到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 -> -e.getValue())
替换为Map.Entry.comparingByValue(Comparator.reverseOrder())
。
答案 1 :(得分:6)
请注意,如果您希望高效实施,则应考虑以下因素:
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
中,然后在不进行任何额外复制的情况下对其进行排序。所以我的解决方案将花费更少的时间和中间记忆。
答案 2 :(得分:1)
public List<TeamResult> process(final Map<String, Team> aggregatedMap) {
return aggregatedMap.entrySet()
.stream()
.map(e -> new TeamResult(e.getKey(),e.getValue()))
.collect(Collectors.toList());
}
答案 3 :(得分:1)
根据相反的值对地图进行排序,并收集列表中的键,并且仅限制列表中的前2个结果
List<String> list = map.keySet().stream()
.sorted((k1, k2)->map.get(k2)- map.get(k1))
.limit(2)
.collect(Collectors.toList())