简体   繁体   English

如何对地图进行排序 <String, List<Summary> &gt;

[英]How to Sort Map<String, List<Summary>>

I need sort a map by attribute of elements of values that are a list. 我需要按列表值元素的属性对地图进行排序。 See the code. 参见代码。

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. 我需要通过元素List的getFavorite_count对地图mostMentionsMap进行排序,以返回已排序的地图。 I'm already sorting the elements of each map item, but I need to use the same sorting criteria for the map. 我已经在对每个地图项的元素进行排序,但是我需要对地图使用相同的排序标准。

I can sort by key see the code. 我可以按键排序查看代码。

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));

But, I have to sort by a attribute of the elements of the values ​​(List ). 但是,我必须按值元素的属性排序(List)。 I do not know if I'm explaining well? 我不知道我讲得好吗?

Well, it's clear from your question that you want to sort the Map by values. 好了,从您的问题中很明显,您想按值对Map进行排序。 And you can do that using: 您可以使用以下方法做到这一点:

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
        ));

Now, it's unclear (and that's what Slaw's comment was about) how you want to sort the values (ie what the valueComparator should be). 现在,尚不清楚(这就是Slaw的评论所要表达的)您希望如何对值进行排序(即valueComparator应该是什么)。 We know you want to sort using Summary::getFavorite_count , but since you have a List of Summary 'ies, the options are multiple. 我们知道你想使用排序Summary::getFavorite_count ,但因为你有一个ListSummary “IES,选项有多个。 Here are a few of these options: 以下是其中一些选项:

1) Sort by maximum: 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) Sort by total: 2)按总数排序:

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

3) Sort by average: 3)按平均值排序:

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

In general when wanting a specific ordering of a map in Java you should probably use a TreeMap. 通常,当需要Java中特定的地图排序时,您可能应该使用TreeMap。 Now, I am supposing .getFavorite_count returns a int so the key will need to be of type Integer as I am not sure making the key of type String will sort a number of type String as you currently have in your return type. 现在,我假设.getFavorite_count返回一个int,因此该键将必须为Integer类型,因为我不确定使String类型的键是否会像您当前在返回类型中那样对String类型的数字进行排序。

You can use the Comparable Interface: 您可以使用可比接口:

public class YourNameOfTheClass implements Comparable</*Your objects, which should be sorted. Example: Car*/> {

/*Your code and stuff…*/

    @Override
    public int compareTo(/*Your object, which you wrote above and the name of it. Example: Car myCar*/) {

        /*
        Now here you should enter your criteria.

        If you want to sort something it should be comparable.

        Usually, this method returns '0', when the two objects, which are compared are equal. So you should write something like this:

        if (this.getFavourite() == car.getFavourite())
            return 0;

        This method returns a negative integer when the first object has a 'smaller' value and a positive integer when it's of greater value.

        Example:
        myCar.compareTo(yourCar) would return 0, if we're actually driving the same car. -1 when my Car is not as good as yours and +1 when my Car is better.
        */
    }
}

After you've defined your comparison criterion, you can sort it simply like this: 定义比较条件后,可以像这样简单地对其进行排序:

Collections.sort(/*The name of your list*/)

I'll demonstrate it: 我将演示它:

public class CompareCars implements Comparable<Car> {

    public static void main (String [] args) {
        List<Car> allCars = new ArrayList<Car>();
        Collections.sort(allCars);
    }

    @Override
    public int compareTo (Car secondCar) {
        if (this.getLicensePlate() == secondCar.getLicensePlate() || this.getHP() == secondCar.getHP())
            return 0;
        if (this.getHP() > secondCar.getHP())
            return 1;
        else
            return -1;
    }

}

You can read more about it here . 您可以在此处了解更多信息。 It should work with maps, too. 它也应该与地图一起使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM