コレクションを操作するためのクラスとして,java.util.Collectionsクラスがあります.このクラスにはListクラスの要素をソートするメソッドが2つ用意されています.それら2つのシグネチャは次の通りです.
static <T extends Comarable<? super T>> void sort(List<T> list) static <T> void sort(List<T> list, Comparator<? super T> c)
前者はjava.lang.Comparableインタフェースを実装したクラスTを用意し,Tを要素として持つリストをソートします.後者は要素Tをもつリストを,java.lang.Comparatorインタフェースを実装したクラスを使用してソートします.前者はソートする要素を定義したクラスにソート順を定義するため,ソート順は1つしか設定できません.後者はソートする要素とソート方法を定義したクラスとが別であるため,ソート順を前者より自由に変えられるのが特徴であると言えます.
ComparableとComparatorにはそれぞれオブジェクトを比較するためのメソッドが定義されており,ソート順はそれらのメソッドの戻り値を参照して決定されます.Comparable,Comparatorのシグネチャと,比較結果を表す戻り値の設計指針は次のとおりです.
- Comparable
public int compareTo(T o);
比較結果 | 戻り値 |
---|---|
oが小さい場合 | 正 |
oが同じ場合 | 0 |
oが大きい場合 | 負 |
- Comparator
int compare(T o1, T o2);
比較結果 | 戻り値 |
---|---|
o1がo2より大きい | 正 |
o1がo2と等しい | 0 |
o1がo2より小さい | 負 |
上記2つのソート方法を次のように実装してソート結果を確認しました.設計が大きく違うので,大規模なプログラムで利用する際には考慮すべき点なように感じます.
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; class ComparableClass implements Comparable<ComparableClass> { private String name; public ComparableClass(String name) { this.name = name; } public int compareTo(ComparableClass comparableClass) { return this.name.compareTo(comparableClass.getName()); } public String getName() { return this.name; } public String toString(){ return this.name; } } class ComparatorClass implements Comparator<String> { public int compare(String string1, String string2) { return string1.compareTo(string2); } } public class CompareTest { public static void main(String[] args) { //Comparableインタフェースによるソート ComparableClass comparableClass1 = new ComparableClass("A"); ComparableClass comparableClass2 = new ComparableClass("B"); ComparableClass comparableClass3 = new ComparableClass("C"); List<ComparableClass> comparableClassList = new ArrayList<ComparableClass>(); comparableClassList.add(comparableClass2); comparableClassList.add(comparableClass3); comparableClassList.add(comparableClass1); System.out.println("List<ComparableClass> : before sort"); for (ComparableClass x: comparableClassList){ System.out.println(x); } Collections.sort(comparableClassList); System.out.println(""); System.out.println("List<ComparableClass> : after sort"); for (ComparableClass x: comparableClassList){ System.out.println(x); } //Comparatorインタフェースによるソート List<String> stringList = new ArrayList<String>(); stringList.add("E"); stringList.add("F"); stringList.add("D"); System.out.println(""); System.out.println("List<String> : before sort"); for (String x: stringList){ System.out.println(x); } Collections.sort(stringList, new ComparatorClass()); System.out.println(""); System.out.println("List<String> : before sort"); for (String x: stringList){ System.out.println(x); } } }
実行結果
List: before sort
B
C
AList
: after sort
A
B
CList
: before sort
E
F
DList
: before sort
D
E
F