17
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Comparatorで学ぶJavaのラムダ式

Last updated at Posted at 2018-07-13

いまさらながら、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

17
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?