技術メモ

神奈川在住のITエンジニアの備忘録。おもにプログラミングやネットワーク技術について、学んだことを自分の中で整理するためにゆるゆると書いています。ちゃんと検証できていない部分もあるのでご参考程度となりますが、誰かのお役に立てれば幸いです。

Javaで複数条件でソートする。

Javaでリストを複数の条件でソートしたい時は、Comparator クラスの comparing() と thenComparing() を使うと簡単に実現できる。

例えば、以下の Work クラスのオブジェクトが複数入った List があるとする。

    class Work {
        private int timeToFinish; // 仕事が終わるまでにかかる時間
        private int reward; // 報酬
        Work(int timeToFinish, int reward) {
            this.timeToFinish = timeToFinish;
            this.reward = reward;
        }
        public int getTimeToFinish() {
            return timeToFinish;
        }
        public int getReward() {
            return reward;
        }
    }

その List について、報酬が高い順に、そして報酬が同じだったら、仕事が終わるまでにかかる時間が少ない順でソートしたいとする。
# つまり、ソートの第一条件が報酬(降順)で、第二条件が仕事が終わるまでにかかる時間(昇順)。

このソートを実現するには以下のように実装する。

        List<Work> works = new ArrayList<>();
        ・・・
        Comparator<Work> workComparator =
                Comparator.comparing(Work::getReward, Comparator.reverseOrder())
                        .thenComparing(Work::getTimeToFinish);
        works.sort(workComparator);

ソートの第一条件にソートの第二条件を繋げて Comparator を作成し、それを sortメソッドの引数として与えている。


以上を踏まえて、例えば以下を実行すると、

        List<Work> works = new ArrayList<>();
        works.add(new Work(1, 3));
        works.add(new Work(3, 8));
        works.add(new Work(2, 6));
        works.add(new Work(3, 7));
        works.add(new Work(1, 4));
        works.add(new Work(4, 6));

        Comparator<Work> workComparator =
                Comparator.comparing(Work::getReward, Comparator.reverseOrder())
                        .thenComparing(Work::getTimeToFinish);
        works.sort(workComparator);
        for (Work work : works) {
            System.out.println("TimeToFinish: " + work.getTimeToFinish() + ", Reward: " + work.getReward());
        }
    }

出力結果は以下にようになる。

TimeToFinish: 3, Reward: 8
TimeToFinish: 3, Reward: 7
TimeToFinish: 2, Reward: 6
TimeToFinish: 4, Reward: 6
TimeToFinish: 1, Reward: 4
TimeToFinish: 1, Reward: 3

期待通り、報酬が高い順に、報酬が同じだったらかかる時間が短い順にソートされている。