ただ、ストレスなく生きたいだけのITエンジニアのブログ -- 弱小エンジニア脱却への道
【初心者向け】javaのラムダ式の使い方(応用編)

こんにちは!ISAMU(@burlesca_isa)です!

今回の対象読者は

  • javaのラムダ式の使い方を具体的に知りたい方

javaのラムダ式の使い方

ラムダ式を使う効果的に使用できる場面は大きく2つあります。

  • コレクションAPIのデフォルトメソッドを利用する
  • 関数型インターフェースを利用する

関数型インターフェースの使い方は他の記事で解説していますが、
今回はデフォルトメソッドを中心に解説していきます。

デフォルトメソッドとは

デフォルトメソッドとは、
インターフェースに定義できる具象メソッドのことです。

インターフェースは基本的に抽象メソッドを定義するものでしたが、
SE8からデフォルトメソッドを利用して具象メソッドを定義できるようになりました。

デフォルトメソッドが定義されているインターフェースを実装すれば、
オーバーライドせずにメソッドを利用することができます。

コレクションAPIのデフォルトメソッド

コレクションAPIにはデフォルトメソッドが定義されています。

コレクションAPIとは「要素の集まりを操作、管理するための方法を定義したアーキテクチャ」のことで、
インターフェースをベースに設計されています。

例としてArrayListクラスについて説明します。

ArrayListクラスListインターフェース実装
ListインターフェースCollectionインターフェース継承しています。

コレクションAPIであるListとCollectionはデフォルトメソッドを持っており
このデフォルトメソッドを使用する時にラムダ式を利用できます。

removeIfメソッドとreplaceAllメソッド

SE8で導入されたデフォルトメソッドは
removeIfメソッドとreplaceAllメソッドがあります。

  • removeIf・・・条件にあったコレクションの要素をすべて削除
  • replaceAll・・・指定された処理を行い、リストの要素を置き換える

という機能があります。

  • Collectionインターフェース・・・removeIf
  • Listインターフェース・・・replaceAll

に定義されています。

このインターフェースを実装しているクラスであれば、
リストの要素を簡単に編集することができます。

前述しましたが、
ListインターフェースはCollectionインターフェースを継承しているため、
Listインターフェースを実装すれば両方のメソッドを使用することができます。

デフォルトメソッドを利用するために必要な知識

デフォルトメソッドを利用するには、関数型インターフェースを覚える必要があります。

removeIfメソッドの構文

default boolean removeIf(Predicate filter)

引数にはPredicate型を渡す必要があります。
このPredicate型というのが関数型インターフェースです。

Predicateインターフェースの抽象メソッドをオーバーライドして、引数にわたすことで利用することができます。

Predicate関数型インターフェースについて知らないとremoveIfメソッドを使用することができません。

replaceAllの構文

default void replaceAll(UnaryOperator operator)

引数にはUnaryOperator型を渡す必要があります。
これも関数型インターフェースです。

関数型インターフェースはラムダ式で記述することが前提

関数型インターフェースはラムダ式で記述することが前提とされているので、
メソッドを一つしか持っていません。

ラムダ式はメソッドを一つしか持たないインターフェースの記述を簡単に書けるようにするためのものです。

関数型インターフェースはそれぞれどんな時に利用するべきか決まっています。

Predicate型

Predicate型はboolean値を戻り値として受け取りたい時に利用します。

Predicate<T> boolean test(T t);

booleanを戻り値に持つtest抽象メソッドが定義されています。

サンプル

removeIfを使用したサンプルコードを示します。
まずは分かりやすくするために匿名関数で示します。

リストに格納された数値が100未満の要素を削除するプログラムです。

asListメソッドは固定のListが返されるため、要素の操作ができません。
なので、ArrayList型としてlist変数に格納しています。

<T>はTypeの略でデータ型を記述します。test(T t)となっているので、
引数のデータ型をに指定します。

Integer型を渡したい場合はPredicate<Integer>とします。

testメソッドをオーバーライドして削除する条件を記述します。

匿名関数をPredicate型のfilter変数へ格納します。

これをremoveIfの引数に渡すことで、リストの要素が削除されます。

ラムダ式に書き換えたサンプル

ラムダ式ではPredicateに関しては一切記載していないように見えます。

ラムダ式では右辺に記述した式や文の結果がbooleanで返ってくる場合は
Predicateを暗黙的に使用するということになっています。

左辺はlist変数のデータ型は<Integer>としているため、
省略することが可能です。

詳しく知りたい方は過去の記事を読んでください。

UnaryOperator型

UnaryOperator型は引数と同じデータ型の戻り値を受け取りたい時に利用します。

UnaryOperator<T> T apply(T t)

Tを戻り値に持つapply抽象メソッドが定義されています。

サンプルコード

replaceAllデフォルトメソッドを利用した、
匿名関数のサンプルを示します。

偶数の場合は10を乗算するというプログラムです。
replaceAllに匿名関数を引数で渡すことでリストの要素が書き換わります。

ラムダ式に書き換えたサンプル

【初心者向け】javaのラムダ式の使い方(応用編)
最新情報をチェックしよう!