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の大体のリソースです
コメントはやさしくお願いいたします^^
座右の銘は、「狭き門より入れ」「願わくは、我に七難八苦を与えたまえ」です^^
コメント