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で対応するべき – サイゼントの技術ブログ