【Java】Listのソート方法(Collections)

プログラミング

基本的にデータのソートはSQLで完結させてしまうのですが、どうしてもプログラム内でソートをしなければいけないことがあります。

今回はJavaのListのソート方法について解説していきます。

Collectionsクラス

Collections (Java Platform SE 8)

Collectionsクラスは、ListやMapに関連するstaticなメソッドが定義されています。その中の1つにソートメソッド(sort())があります。

sort()はオーバーロードされていて、Comparableを使うものとComparatorを使うものがあります。

修飾子と型static <T extends Comparable<? super T>> void
メソッドsort(List<T> list)
説明リストをComparableで定義された順序でソートします。
修飾子と型static <T> void
メソッドsort(List<T> list, Comparator<? super T> c
説明リストをComparatorで定義された順序でソートします。

Comparableによるソート

シンプルなIntegerのListをソートしてみます。

List<Integer> list = new ArrayList<>();
list.add(10);
list.add(4);
list.add(6);
list.add(2);
list.add(8);
Collections.sort(list);

これを表示すると昇順にソートされていることが分かります。

2
4
6
8
10

降順にソートするには次のようにします。

Collections.sort(list, Collections.reverseOrder());
10
8
6
4
2

StringのListもIntegerの場合と変わりはありません。並び順は文字コードの順となります。

List<String> list = new ArrayList<>();
list.add("ABC");
list.add("abc");
list.add("123");
list.add("1A");
list.add("A12");
Collections.sort(list);
123
1A
A12
ABC
abc

では自作したクラスのListをソートしてみます。次のようなMyClassクラスを定義し、item1, item2の順でソートすることを考えます。

public class MyClass {
  private int item1;
  private String item2;
  public MyClass(int item1, String item2) {
    this.item1 = item1;
    this.item2 = item2;
  }
}
List<MyClass> list = new ArrayList<>();
list.add(new MyClass(1, "ABC"));
list.add(new MyClass(2, "ABC"));
list.add(new MyClass(1, "BAC"));
list.add(new MyClass(0, "CCC"));
list.add(new MyClass(2, "000"));
Collections.sort(list);

実はこのままではソートされません。ソートするためには次のようにMyClassクラスでComparableを実装する必要があります

public class MyClass implements Comparable<MyClass> {
  //省略
  @Override
  public int compareTo(MyClass another) {
    int cmp = 0;
    if ((cmp = this.item1 - another.item1) != 0) {
      return cmp;
    }
    return this.item2.compareTo(another.item2);
  }
}

説明を省いていましたが、IntegerやStringはComparableが実装されています。そのためそのままでもソートが実行されます。

Comparableを実装する場合は、compareTo()をオーバーライドする必要があります。compareTo()の基本的な考え方は、自身の要素が比較要素より大きければ正の値、小さければ負の値、同じであれば0を返すように実装します。これにより昇順にソートされます。

MyClassクラスのように複数の項目でソートしたい場合は、ソートしたい順に項目を比較します。

Comparatorによるソート

同じようにIntegerのListからソートしてみます。

List<Integer> list = new ArrayList<>();
list.add(10);
list.add(4);
list.add(6);
list.add(2);
list.add(8);
Comparator comparator = new Comparator<Integer>() {
  @OVerride
  public int compare(Integer a, Integer b) {
    return a.compareTo(b);
  }
};
Collections.sort(list, comparator);

Comparatorでソートする場合は、無名クラスとしてComparatorを実装します。そして実装の際にcompare()をオーバーライドする必要があります。基本的な考え方は先程のcompareTo()と同じです。

降順にソートする場合は次のようにします。

Collections.sort(list, comparator.reversed());

しかし、次のようにComparatorを実装しなくても同じように昇順にソートされます。

Collections.sort(list, null);

Comparatorを実装しなかった場合は、Comparableに従ってソートされます。つまり、ComparatorによるソートはComparableとは別のルールでソートしたい場合に実装します

例えばStringを文字コードでなく、文字数の順でソートしたい場合は次のようにします。

List<String> list = new ArrayList<>();
list.add("ABC");
list.add("abc");
list.add("123");
list.add("1A");
list.add("A12");
Comparator comparator = new Comparator<String>() {
  @Override
  public int compare(String a, String b) {
    return a.length() - b.length();
  }
};
Collections.sort(list, comparator);
1A
ABC
abc
123
A12

ラムダ式による実装

Comparatorによるソートはラムダ式によって次のように実装することもできます。

Collections.sort(list, (a, b) -> {
  return a.compareTo(b);
});

 

- Javaのおすすめ書籍はコチラ -

コメント

タイトルとURLをコピーしました