如何对Map <string,list <summary =“” >>进行排序

时间:2018-08-02 19:58:36

标签: 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;
}
  

我需要根据地图的getFavorite_count对地图mostMentionsMap进行排序   元素列表返回排序后的地图。         我已经在对每个地图项的元素进行排序,但是我需要对地图使用相同的排序条件。

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

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)的元素的属性进行排序。 我不知道我的解释是否很好?

3 个答案:

答案 0 :(得分:2)

好吧,从您的问题中可以明显看出,您想按值对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进行排序,但是由于您有List个实体中的Summary个,因此选项是多个。以下是其中一些选项:

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

答案 1 :(得分:0)

通常,当需要Java中特定的地图排序时,您可能应该使用TreeMap。现在,我假设.getFavorite_count返回一个int,所以该密钥将需要为Integer类型,因为我不确定使String类型的密钥会像您当前在返回类型中那样对String类型的数字进行排序。

答案 2 :(得分:0)

您可以使用可比界面:

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.
        */
    }
}

定义比较条件后,可以像这样简单地对其进行排序:

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

我将演示它:

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

}

您可以详细了解here。它也应该适用于地图。