グループ化と並べ替えダブル一覧<人>

callmebob:

私はすべてそこにマニュアルおよびすべてのSOの質問を経たが、それでも、このアウトを把握することができませんでし...

私は(整数は年齢を表し)リストを持っています:

List<Person> people = Arrays.asList
    (
            new Person("bob", 10),
            new Person("sue", 4),
            new Person("tom", 37),
            new Person("jim", 10),
            new Person("boo", 4),
            new Person("ekk", 53),
            new Person("joe", 10)
    );

する必要がある:

  • グループ年齢別リスト、
  • グループサイズ(降順)で並べ替え、
  • 年齢でソート(降順)

その結果、上記の例を使用して、このようでなければならないであろう。

{10=[bob, jim, joe],4=[sue, boo], 53=[ekk], 37=[tom]}

私が何をしようとしました:

私はと流れずに試してみました。私は両方で失敗しました。

注:私は傾くだろうがないストリームソリューションストリームがはるかに遅い(私はSystem.nanoTimeの()を使用)しているように以下のコードの私のテストから、それはそうなので、。これらの3つの操作は、それがわずかな違いを生むことがあり、何千回を毎回行われます。

ここでストリームを使用すると、私がやったことです:

List<List<Person>> grpd = new ArrayList<>
    (
            people.stream()
                    .collect
                            (
                                    groupingBy(Person::getAge, toList())
                            )
                    .values()
    );
grpd = grpd.stream().sorted((a, b) -> Integer.compare(b.size(), a.size())).collect(toList());

いいえアプローチをストリーム:

    Map<Integer, List<Person>> grouped = new HashMap<>();
    for (Person person : people)
    {
        if (grouped.containsKey(person._age))
        {
            grouped.get(person._age).add(person);
        } else
        {
            List<Person> p = new ArrayList<>();
            p.add(person);
            grouped.put(person._age, p);
        }
    }


    List<Map.Entry<Integer, List<Person>>> entries = new ArrayList<>(grouped.entrySet());
    Collections.sort(entries, new Comparator<Map.Entry<Integer, List<Person>>>()
    {
        @Override
        public int compare(Map.Entry<Integer, List<Person>> o1, Map.Entry<Integer, List<Person>> o2)
        {
            return Integer.compare(o2.getValue().size(), o1.getValue().size());
        }
    });
    Map<Integer, List<Person>> sortedBySize = new LinkedHashMap<>();
    for (Map.Entry<Integer, List<Person>> entry : entries)
    {
        sortedBySize.put(entry.getKey(), entry.getValue());
    }

問題:私はどちらかの場合に、最終的な並べ替えを追加する方法は考えています。

public class Person
{
    public String _name;
    public int _age;
    public int getAge() { return _age; }

    public Person(String name, int age)
    {
        _name = name;
        _age = age;
    }

    @Override
    public String toString()
    {
        return _name;
    }
}
フェデリコ・ペラルタシャフナー:

あなたはまた、非ストリーム・ソリューションについて尋ねてきたように、ここにあります:

Map<Integer, List<Person>> grouped = new HashMap<>();
people.forEach(person -> grouped.computeIfAbsent(
        person.getAge(), 
        k -> new ArrayList<>())
    .add(person));

年齢によるこのグループ。さて年齢降順による最初のグループサイズの降順でソートのエントリ、してみましょう:

List<Map.Entry<Integer, List<Person>>> toSort = new ArrayList<>(grouped.entrySet());
toSort.sort(
    Comparator.comparingInt((Map.Entry<Integer, List<Person>> e) -> e.getValue().size())
              .reversed()
              .thenComparingInt(Map.Entry.comparingByKey().reversed()));

さて、toSortエントリのソートされたリストです。あなたは、新しいマップにこれらのエントリを配置する必要があります。

Map<Integer, List<Person>> sorted = new LinkedHashMap<>();
toSort.forEach(e -> sorted.put(e.getKey(), e.getValue()));

そして、sortedあなたが望む結果を保持します。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=202057&siteId=1