こんにちは。ハンドルネーム「Javaを復習する初心者」です。このサイトはプログラミング言語Javaの復習・学習をするブログです。プログラムの開発・実行はEclipseで行ってます。
スポンサーリンク
お知らせ
  • 参考文献のページ作りました。
  • Amazon.co.jpアソシエイトに参加していますが、参考文献の紹介はもしもアフィリエイトに統一しました。
  • 2016年10月9日からは投稿ペースを落とします。週1回くらいにする予定です。
スポンサーリンク

オブジェクト配列のソート

こんにちは。「Javaを復習する初心者」です。今回はオブジェクトの配列をソートする方法について書こうと思います。

前回はint型の配列をArrays.sortメソッドでソートしました。順番は昇順です。int型なので数値の大小関係でソートしてくれます。

オブジェクト型のソートの場合は「static <T> void sort(T[] a, Comparator<? super T> c)」を使います。第2引数が大小関係を定義するクラスになります。Comparatorはインターフェースであるため、Comparatorを実装したクラスを第2引数に指定します。このインターフェースの定義を抜粋すると以下になります。

public interface Comparator<T> {

    int compare(T o1, T o2);
    
    .
    .
    .
}

返却するintの値は以下の通りです。

順序関係

返却値
o1がo2より小さい

負の数
o1とo2が等しい

0
o1がo2より大きい

正の数

Comparatorの実装クラスを定義

今回はソートする対象となるMyObjクラスを定義しました。String型変数nameとint型ageをフィールドに持ちます。このクラスのインスタンスを生成し、ageにランダムな値を設定して、ageで昇順で並べ替えるサンプルを作りました。

以下はソースと実行結果です。

package arraysTest;

import java.util.Arrays;
import java.util.Comparator;
import java.util.Random;

public class SortObj {


    public static void main(String[] args) {

        Random random = new Random();

        MyObj[] myObjs = new MyObj[5];
        myObjs[0] = new MyObj("test1", random.nextInt(100));
        myObjs[1] = new MyObj("test2", random.nextInt(100));
        myObjs[2] = new MyObj("test3", random.nextInt(100));
        myObjs[3] = new MyObj("test4", random.nextInt(100));
        myObjs[4] = new MyObj("test5", random.nextInt(100));

        System.out.println("ソート前");
        for (MyObj o : myObjs) {
            System.out.println(o.name + " " + o.age);
        }

        Arrays.sort(myObjs, new MyObjComp());

        System.out.println("ソート後");
        for (MyObj o : myObjs) {
            System.out.println(o.name + " " + o.age);
        }

    }

}
class MyObj {
    public String name;
    public int age;

    public MyObj(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
}

class MyObjComp implements Comparator<MyObj> {

    @Override
    public int compare(MyObj o1, MyObj o2) {
        // o1の方が昇順で上なら負の数を返す。
        return o1.age - o2.age;
    }

}
ソート前
test1 6
test2 60
test3 25
test4 2
test5 14
ソート後
test4 2
test1 6
test5 14
test3 25
test2 60

Comparatorインターフェース

上記サンプルは、Comparatorの実装クラスを定義してArrays.sortメソッドの第2引数に指定していますが、匿名クラスで渡すこともできます。また、Comparatorインターフェースは@FunctionalInterfaceがついているため、ラムダ式も使えます。ラムダ式を使った例が以下になります。

package arraysTest;

import java.util.Arrays;
import java.util.Random;

public class SortObjLambda {


    public static void main(String[] args) {

        Random random = new Random();

        MyObj[] myObjs = new MyObj[5];
        myObjs[0] = new MyObj("test1", random.nextInt(100));
        myObjs[1] = new MyObj("test2", random.nextInt(100));
        myObjs[2] = new MyObj("test3", random.nextInt(100));
        myObjs[3] = new MyObj("test4", random.nextInt(100));
        myObjs[4] = new MyObj("test5", random.nextInt(100));

        System.out.println("ソート前");
        for (MyObj o : myObjs) {
            System.out.println(o.name + " " + o.age);
        }

        Arrays.sort(myObjs, (a, b) -> a.age - b.age);

        System.out.println("ソート後");
        for (MyObj o : myObjs) {
            System.out.println(o.name + " " + o.age);
        }

    }

}

今回の場合、フィールドageの差のみをreturnすればよいため、「(a, b) -> a.age – b.age」という記述だけで十分になります。型の類推もしてくれるようです。