コンテンツにスキップ

ラムダ式と匿名クラス

配列の整列

インタフェースを実装したクラスを引数に取るメソッドがあります。

例えば、配列を整列する場合、sortというメソッドが使用できます。

Integer[] nums = {5,8,9,4,7};

// 整列
Arrays.sort(nums);

for(int n : nums) {
    System.out.println(n);
}

ただし、通常は昇順にしかなりません。 これを他の順番で整列するには、第二引数を指定する必要があります。第二引数はインタフェースComparatorを実装したクラスのインスタンスを渡します。

Arrays.sort(nums, Comparatorを実装したクラスをnewしたもの );

Comparatorインタフェースでは compareというメソッドがありますので、Comparatorインタフェースを実装したクラスは必ず compareメソッドを作らなくてはなりません。compareメソッドは引数が2つのメソッドでこれを比較して結果(どちらが先か)を返します。

Arrays.sort内では、渡されてきたインスタンスのcompareメソッドを呼び出して2つの要素の比較を行います。内部では、compareメソッドを何回も呼び出して全要素を比較し、整列を行うわけです。

通常のインタフェース

Comparatorインタフェースのcompareメソッドは引数が2つ、戻り値はint型です。 その2つを比較し、以下のように返す必要があります。

  • 第一引数が先:負の数
  • 同じ:0
  • 第二引数が先:正の数

これは整数なら「第一引数 - 第二引数」で求めることが出来ます。逆順(降順)にしたい場合、「第二引数 - 第一引数」で求められます。

Comparatorインタフェースを実装すると、以下のようになります(昇順の場合)。

class MyComparator implements Comparator<Integer>{

    public int compare(Integer a, Integer b) {
        return a - b;
    }

}

Arrays.sortではこれをnewして渡します。

Arrays.sort(nums, new MyComparator());

匿名クラス

このように、インタフェースを実装するには新たなクラスを作り、実装する必要があります。

しかし、一度しか使用しない場合など、わざわざクラスを定義するまでもない場合、引数に直接クラスの実装を書くことが出来ます。名前を付けずにクラスを作るので、匿名クラスと呼びます。

匿名クラスは以下のように書きます。

new インタフェース名(){
    インタフェースを実装したクラスの中身
}

Comparatorの例を書き直してみます。

Arrays.sort(nums, new Comparator<Integer>(){

    public int compare(Integer a, Integer b) {
        return a - b;
    }

});

ラムダ式

インタフェースで実装しなければならないメソッドが1つだけであれば、ラムダ式を使うことが出来ます。

ラムダ式を使う場合、インタフェースを実装したクラスを作る必要はありません。 必要になるメソッドだけ(今回はcompareメソッド)を以下の形で渡します。

 (引数,,)-> 処理内容 

つまり、以下のようになります。

Arrays.sort(nums, (Integer a, Integer b)-> { return a - b; } );

なお、引数は型を省略できます。変数名だけでかまいません。

Arrays.sort(nums, (a, b)-> { return a - b; } );

さらに、{}を省略することができます。そのときには、return は省略します。

Arrays.sort(nums, (a, b)-> a - b );

これにより、インタフェースを実装したクラスを作ってnewしたことと同じことになります。

Listの場合

Listの整列にもsortメソッドが使用できます。Collectionsクラスのsortメソッドで同じように Comparatorインタフェースを使用します。 これもラムダ式で書くことが出来ます。

// リストの初期化
List<Integer> list = Arrays.asList(20, 15, 12, 18);

// ラムダ式を使った整列
Collections.sort(list, (a,b)-> a - b );

// 表示
System.out.println(list);