Help us understand the problem. What is going on with this article?

Comparatorで学ぶJavaのラムダ式

More than 1 year has passed since last update.

いまさらながら、Javaのラムダ式についての解説を書きます。

Javaのラムダ式

そもそもラムダ式は無名関数を記述する方法として、関数型言語でよく使われていたものです。
関数に関数を渡すときなど、一時的な関数を作るときに使います。

Javaにおいては関数というものが存在しません(メソッドは必ずクラスの中に定義される)。
そのため、Javaのラムダ式は「単一の抽象メソッドを持つインターフェースのインスタンスを生成して受け渡す」という挙動になります。
単一のメソッドに限定されるのは、ラムダ式では1つの式しか記述できないため、複数のメソッドを持つインターフェースだとどのメソッドの式かが定まらないためです。

記述の方法としては

(引数) -> {処理}

と書きます。
引数や処理が1つしかない場合、カッコは省略できます。

具体例としてCollectionssortメソッドを見ていきます。
これは第1引数のListに対してソートを実行するメソッドですが、第2引数にComparatorインターフェースのインスタンスを渡すとcomparableメソッドを使ってソート順を判断してくれます。
例えば、文字列のリスト(strList)を文字の長さでソートしたいときは無名関数だと以下のように記述できます。

Collections.sort(strList, new Comparator(){
    @Override
    public int compare(String s1, String s2) {
        return s1.length() - s2.length();
    }
})

Comparatorクラスはcompareメソッドだけが定義されているインターフェースなのでラムダ式で以下のように書き換えることができます。

List<String> strList = Arrays.asList("a","ccc","bb");
Collections.sort(strList, (s1, s2) -> s1.length() - s2.length());
System.out.println(strList); // [a, bb, ccc]

関数型インターフェースとメソッド参照

Comparatorクラスにはcomparingメソッドが以下のように定義されています。

comparing(Function<? super T,? extends U> keyExtractor);

引数の型がFunction<? super T,? extends U>となっていますが、これは関数型インターフェースの一種です。
関数型インターフェースはラムダ式が使えるインターフェースであり、様々な種類が用意されています。
今回のFunction<? super T,? extends U>は引数がT、戻り値がUの型を持つインスタンスであることを示しています。
TとUについては、以下のように定義されています。
<T,U extends Comparable<? super U>> Comparator<T>

Tは比較対象のインスタンスの型。Uは比較するためのフィールドの型です。
そのため、この関数型インターフェースはTのインスタンス同士を比較するための情報Uを返す式であるという意味になります。

先ほどのCollections.sortの処理をcomparingメソッドで書くと以下のようになります。

Collections.sort(strList, comparing(s -> s.length()));

s -> s.length()の部分は、String型インスタンスsのlengthメソッドを呼び出すという意味なので、メソッド参照で書き換えることができます。
メソッド参照はあるインスタンスに対して、そのクラスのメソッドを呼び出すという処理を簡単に書ける記述方法です。
クラス名::メソッド名で記述します。
先ほどの例をメソッド参照で書くと以下のようになります。

Collections.sort(strList, comparing(String::length));

参考
(o1, o2) -> o1 - o2 なんて呪文はもうやめて! - Java8でのComparatorの使い方
JavaDoc:Comparator

frost_star
まだまだ半人前プログラマー。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした