java - 如何对 Map<String, List<Summary>> 进行排序

标签 java lambda java-8 comparator

我需要按列表值元素的属性对映射进行排序。请参阅代码。

public Map<String, List<Summary>> getMostMentions() throws Exception {

    List<Tweet> tweets;
    try {
        tweets = getApiFromTweet().getTweets();
    } catch (Exception e) {
        throw new Exception(e);
    }


    List<Summary> summary = new ArrayList<>();

    tweets.forEach(t -> {
        summary.add(
                new Summary(
                        t.getUser().getScreen_name(), 
                        t.getFollowersCount(), 
                        t.getRetweet_count(),                   
                        t.getFavorite_count(), 
                        t.getText(), 
                        t.getCreated_at(),
                        appConfig.getProfileLink(t.getUser().getScreen_name()),
                        appConfig.getTweetLink(t.getUser().getScreen_name(), t.getId())));
    });

    Map<String, List<Summary>> mostMentionsMap = summary.stream().collect(Collectors.groupingBy(Summary::getScreen_name));

    mostMentionsMap.forEach((k,v) -> {
        v.sort(Comparator.comparing(Summary::getFavorite_count).reversed());
    });


    return mostMentionsMap;
}

I need sort the map mostMentionsMap by getFavorite_count of the elements List to return map sorted. I'm already sorting the elements of each map item, but I need to use the same sorting criteria for the map.

我可以按键排序查看代码。

LinkedHashMap<String, List<SummaryTweet>> mapSorted = mostMentionsMap.entrySet().stream()
                .sorted(Map.Entry.comparingByKey())             
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
                        (oldValue, newValue) -> oldValue, LinkedHashMap::new));

但是,我必须按值(List)元素的属性进行排序。 不知道我解释得好不好?

最佳答案

嗯,从您的问题中可以清楚地看出您希望按值对 Map 进行排序。您可以使用以下方法来做到这一点:

Comparator<List<Summary>> valueComparator;

LinkedHashMap<String, List<Summary>> mapSorted = mostMentionsMap.entrySet().stream()
        .sorted(Map.Entry.comparingByValue(valueComparator))
        .collect(Collectors.toMap(
                Map.Entry::getKey, Map.Entry::getValue,
                (oldValue, newValue) -> oldValue, // or throw here (just in case)
                LinkedHashMap::new
        ));

现在,还不清楚(这就是 Slaw's comment 的目的)如何对值进行排序(即 valueComparator 应该是什么)。我们知道您想使用 Summary::getFavorite_count 进行排序,但由于您有 SummaryList,因此选项有多个。以下是其中一些选项:

1)按最大值排序:

// assumes Summaries are sorted by: Comparator.comparing(Summary::getFavorite_count).reversed()
Comparator.<List<Summary>>comparingInt(list -> list.isEmpty()
        ? 0
        : list.get(0).getFavorite_count()
).reversed();

2)按总数排序:

Comparator.<List<Summary>>comparingInt(list -> list.stream()
        .mapToInt(Summary::getFavorite_count)
        .sum()
).reversed();

3)按平均值排序:

Comparator.<List<Summary>>comparingDouble(list -> list.stream()
        .mapToInt(Summary::getFavorite_count)
        .average().orElse(0)
).reversed();

关于java - 如何对 Map<String, List<Summary>> 进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51661278/

相关文章:

java - 控制 Java 中函数的顺序

c# - 修改Linq代码,加入AND语句加入

c# - C# 中等效的 Objective-C 代码块

amazon-web-services - AWS Lambda SAM,指定多个策略

java - 从安装的 java 8 JDK 编译 java 6

java - 为什么 Oracle 仍然为非开发人员桌面 JRE 提供 Java 8?

java - JTextField 中的自定义文本约束

java - 无法在 Java 中执行 "like"查询

java - Webview和loadurl在另一个类中调用

docker - Docker上运行的springboot无法从资源中读取文件