Java8のComparatorの使い方(Collectionsクラスのsortメソッド)
Java8からComparatorの使い方が大変簡単になりました。
Integer型のlistが適当に並んでいるとします。
これを昇順にソートするには以下のようにnaturalOrderメソッドを使います。
Collections.sort(list, Comparator.naturalOrder());
以下、例です。
import java.util.List;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Collections;
public class Sample {
public static void main(String[] args) {
List list = Arrays.asList(3,2,8,4,1);// 順不同
Collections.sort(list, Comparator.naturalOrder());
System.out.println(list);
}
}
結果は以下のように昇順にソートされます。
1, 2, 3, 4, 8
逆に降順にソートしたい場合はreverseOrderメソッドを使います。
import java.util.List;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Collections;
public class Sample {
public static void main(String[] args) {
List list = Arrays.asList(3,2,8,4,1);// 順不同
Collections.sort(list, Comparator.reverseOrder());
System.out.println(list);
}
}
結果は以下のように降順にソートされます。
8, 4, 3, 2, 1
reverseメソッド
Collections.reverseメソッドはリストを単純に逆順(addした順の逆)に並び替えます。
import java.util.List;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Collections;
public class Sample {
public static void main(String[] args) {
List list = Arrays.asList(3,2,8,4,1);// 順不同
Collections.reverse(list);
System.out.println(list);
}
}
結果は以下のようにaddした順の逆順に並び替えられます。
1, 4, 8, 2, 3
Streamのsortedを使う
Streamのsortedを使ってソートすることも可能です。
import java.util.List;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Collections;
public class Sample {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(3,2,8,4,1);// 順不同
Object[] ret = list.stream().sorted(Comparator.naturalOrder()).toArray();
System.out.println(Arrays.toString(ret));
}
}
Comparator.naturalOrder()を指定しているので、結果は以下のように昇順にソートされます。降順にソートしたい場合はComparator.reverseOrder()を指定します。
1, 2, 3, 4, 8
Listの要素が独自クラスのインスタンス(オブジェクト)の場合
ListがintだったりStringだったりする場合は理解できるけど、独自クラスだった場合のソート方法がわからなかったりします。
従業員を表すEmployeeクラスです。
public class Employee {
// フィールド
private String name;
private int age;
// コンストラクタ
public Employee(String name, int age) {
this.name = name;
this.age = age;
}
// 各アクセサ
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Employeeクラスのオブジェクトのリストのソートをします。以下はList.sortメソッド(since 1.8)を使用して名前の昇順でソートする例です。
List<Employee> list = new ArrayList<Employee>();
list.add(new Employee("tanaka", 44));
list.add(new Employee("takahashi", 40));
list.add(new Employee("minami", 30));
list.add(new Employee("higashiguchi", 32));
list.add(new Employee("adachi", 200));
list.add(new Employee("rasubusu", 25));
// 名前の昇順にソート
list.sort(Comparator.comparing(Employee::getName,Comparator.naturalOrder()));
// 標準出力
list.forEach(s -> System.out.println(s.getName() + " : " + s.getAge()));
その他にもソート方法があります。例えばComparatorのcompareメソッドをオーバーライドするなどです。
List<Employee> sortedList = list.stream().sorted(new Comparator<Employee>(){
@Override
public int compare(Employee o1, Employee o2) {
return o1.getName().compareTo(o2.getName());
}
}).collect(Collectors.toList()); // 注
// 標準出力
sortedList.forEach(s -> System.out.println(s.getName() + " : " + s.getAge()));
Comparator.comparingメソッド
これもComparator.comparingメソッドを使用すればもうちょっときれいに書けます。
Comparator<Employee> comp = Comparator.comparing(Employee::getName); List<Employee> sortedList = list.stream().sorted(comp).collect(Collectors.toList()); // 注 // 標準出力 sortedList.forEach(s -> System.out.println(s.getName() + " : " + s.getAge()));
Collections.sortメソッドの第一引数にリスト、第二引数にComparator.comparingメソッドを指定することでソートすることができます。
Comparator<Employee> comp = Comparator.comparing(Employee::getName,Comparator.nullsFirst(Comparator.naturalOrder())); Collections.sort(list, comp); // 標準出力 list.forEach(s -> System.out.println(s.getName() + " : " + s.getAge()));
ソートするキーにnullが含まれる場合
今までの書き方でも問題ないと思いますが、ソートキーにnullが含まれる可能性がある場合はヌルポで落ちる可能性があります。
この場合は、nullを考慮してあげます。
| null | メソッド |
|---|---|
| 先頭行 | Comparator.nullsFirstメソッド |
| 最終行 | Comparator.nullsLastメソッド |
以下はnullの場合、先頭にもってきて名前順にソートする例です。
List<Employee> list = new ArrayList<Employee>();
list.add(new Employee("tanaka", 44));
list.add(new Employee("takahashi", 40));
list.add(new Employee("minami", 30));
list.add(new Employee("higashiguchi", 32));
list.add(new Employee("adachi", 200));
list.add(new Employee("rasubusu", 25));
list.add(new Employee(null, 25)); // キーがnullになっている
Comparator<Employee> comp = Comparator.comparing(Employee::getName,Comparator.nullsFirst(Comparator.naturalOrder()));
List<Employee> sortedList = list.stream().sorted(comp).collect(Collectors.toList()); // 注
sortedList.forEach(s -> System.out.println(s.getName() + " : " + s.getAge()));
Java8のComparatorインタフェースで複合ソートする

KHI入社して退社。今はCONFRAGEで正社員です。関西で140-170/80~120万から受け付けております^^
得意技はJS(ES6),Java,AWSの大体のリソースです
コメントはやさしくお願いいたします^^
座右の銘は、「狭き門より入れ」「願わくは、我に七難八苦を与えたまえ」です^^

コメント