[Java]複数条件で大きい順に並び替える方法

記事内に広告が含まれています。

javaの備忘録です。

javaで複数条件のソートについて、以下の2通りの方法をまとめます。

  • Stream API を使う方法
  • Comparatorインタフェースにオーバーライドする方法

ソートに使うクラス

以下のような value1と value2 の2つのフィールドを持つ TestObject クラスを使ってデモをします。

     //クラス
        class TestObject {
            //フィールド
            private int value1;
            private int value2;
            

            //コンストラクタ
            TestObject(int v1, int v2){
                this.value1 = v1;
                this.value2 = v2;
                
            }
            
            public String toString(){
                return "["+this.getValue1() +","+this.getValue2()+"]";
            }

            //getter
            public int getValue1(){
                return this.value1;
            }
            public int getValue2(){
                return this.value2;
            }
            
        }
        
     //インスタンスをまとめるリスト
        ArrayList<TestObject> list = new ArrayList<>();
        //TestObjectの3つのインスタンスを格納
        list.add(new TestObject(1, 3));
        list.add(new TestObject(10,20));
        list.add(new TestObject(1, 100));

        System.out.println(list); //[[1,3], [10,20], [1,100]]

方法1. Stream API を利用する

        List<TestObject> sorted = list.stream()
            .sorted(Comparator.comparing(TestObject::getValue1)
                    .thenComparing(TestObject::getValue2)
                    .reversed()
            ).collect(Collectors.toList());

まずは .stream()で Stream APIを利用する準備をします。

その後、.sorted(Comparator) にて、Comparatorの定義する規則に従って並べ替えをします。

並べかえの規則は、以下のロジックで展開します。

Comparator.comparing(TestObject::getValue1) // まずは value1を降順(小さい順で)
.thenComparing(TestObject::getValue2) // value1が同じ場合はvalue2を降順で
.reversed()                           // 降順->昇順(大きい順)に逆転させる

最後に、.collect(Collectors.toList()) で List 型に戻してあげます。

System.out.println(sorted);
//[[10,20], [1,100], [1,3]]

方法2. Comparator インタフェースを利用する

if分岐では、最初の2つでvalue1の大きい順に並べ、value1同士が同じ値なら value2を大きい順に並べています。

        //複数条件でのソート
        Collections.sort(list, new Comparator<TestObject>(){
            @Override
            public int compare(TestObject obj1, TestObject obj2){
                if (obj1.value1 > obj2.value1){
                    return -1;
                }else if(obj1.value1 < obj2.value1){
                    return 1;
                }
                else if(obj1.value2 > obj2.value2){
                    //obj1.value1 == obj2.value1の場合
                    
                    return -1;
                }else if(obj1.value2 < obj2.value2){
                    return 1;
                }else{
                    return 0;
                }
            }
        });

この結果、以下のように出力されることを確認できます。

System.out.println(list);
//[[10,20], [1,100], [1,3]]

まとめと参考

Javaの勉強を始めて日が浅いため備忘録的な側面が強いですが、参考になれば幸いです。

参考文献・出典は以下の通りです。

Java本格入門 ~モダンスタイルによる基礎からオブジェクト指向・実用ライブラリまで
誕生から20年を迎え,幅広い分野のプログラミングに欠かせないJavaの基礎から応用までをしっかり解説。Javaの最新仕様(Java 8)に基づく文法から,オブジェクト指向やデザインパターン,そしてビルド,ドキュメンテーション,品質への配慮な...
java:ソートキーが複数存在する場合、一時的なフォーマット変更ではなく独自Comparatorで対応するべき – サイゼントの技術ブログ
Java
スポンサーリンク