Open4

Java SE11 Gold 備忘録 ポイント

不眠不Q不眠不Q

第2章:関数型インタフェースとラムダ式

関数型インターフェースとは?
java.util.functionに含まれている様々なインタフェースたちを、関数型インタフェースと呼ぶ。Java8で追加されたLambdaを「実装すべき抽象メソッドが一つしかないインタフェースを具現化したもの」と言いますが、ここでいう「実装すべき抽象メソッドが一つしかないインタフェース」のことが関数型インタフェースです。

・以下の関数型インタフェースは、派生形も含めすべてのシグネチャ(引数、戻り値、型)を把握しておくこと。Supplier、Consumer、Predicate、Function、Runnable、Callable

インターフェースの種類
java.util.function.Predicate
引数を1つ受け取り、boolean型で戻す。メソッドはtest(T)
java.util.function.BiPredicate
引数を2つ受け取る。boolean型で戻す。メソッドはtest(T, U)
java.util.function.Function
引数は2つ受け取る。メソッドはapply(T)
java.util.function.BiFunction
3つのパラメータを受け取るが、1つ目と2つ目は引数の型として、3つ目は戻り値の型として使われます。
java.util.function.UnaryOperator
戻り値型T, apply(T)メソッド。1つの値を処理して同じ型の結果を戻す処理。
リストの値を一律に処理する場合に使用できる。

・ラムダ式の文法を把握すること。Eclipseなどで実際にサンプルをコーディングして慣らすのがオススメ。同時にメソッド参照の書き方についても慣れておくと選択肢を絞り込みやすい。

不眠不Q不眠不Q

##Predicatetとは?
Predicateを日本語に訳すと「断定する」という意味になります。言葉の通り、引数を通して何らかの判断をする処理を定義するためのものです。例えば、戻り値がboolean型の処理をラムダ式で変数に代入して簡単に呼び出せるようにできます。Predicateはtestメソッドを持っています。そのメソッドは引数を1つ受け取り、その引数を使って、その結果をboolean型で戻します。サンプルコードを通して使い方を説明していきます。

##どうやって使うの?
サンプルコードでは理想の男性を絞るためにMainクラスでif文を使って絞り込んでいきます。

public class Man {
	private int hight;
	private int income;
	private String looks;
	private int age;

	public Man(int hight, int income, String looks, int age) {
		this.hight = hight;
		this.income = income;
		this.looks = looks;
		this.age = age;
	}
	public int getHight() {
		return hight;
	}
	public int getIncome() {
		return income;
	}
	public String getLooks() {
		return looks;
	}
	public int getAge() {
		return age;
	}
}

普通にif文を使用すると複雑な文になってしまいます。

Man man = new Man(170,900,"hot",20);
if(getHight > 170 && getIncome > 800||
   getLooks == hot && age <30){
}

それを解消するためにPredicateインターフェースを利用します。
下記のコードはPredicateオブジェクトを組み合わせた論理演算を実行しています。

import java.util.function.Predicate;

public class Main {
  public static void main (String[] args) {

	 Predicate<Man> isHight = m -> m.getHight() > 170;
	 Predicate<Man> isIncome = m -> m.getIncome()<1000;
	 Predicate<Man> isLooks = m -> m.getLooks()=="hot" ;
	 Predicate<Man> isAge = m ->m.getAge()<35;
	 Predicate<Man> type = isHight.and(isIncome).or(isLooks.and(isAge));
	 Man man = new Man(170,900,"hot",20);
	if(type.test(man)) {
		System.out.println("OK");
	}else {
		System.out.println("NG");
	}
  }
}

##BiPredicateとは?
Predicateは引数を1つ受け取るのに対してBiPredicateは2つの引数を受け取って何らかの判断をする処理を記述します。Predicateメソッドを同じくtestメソッドを持ちます。

##どのように使うの?
サンプルコードを通して説明していきます。
下記のコードはBiPredicateは2つのString型を受け取り、変数strがsuffixで終わっているかをendsWithを利用して判定しています。

import java.util.function.BiPredicate;

public class Sample {
	public static void main(String[] args) {
		BiPredicate<String, String> b=
				(str, suffix) -> str.endsWith(suffix);
		System.out.println(b.test("sample.class", ".class"));
	}
}
不眠不Q不眠不Q

andThenメソッド
composeメソッド

共通点:Functionの合成をする
相違点:合成の順番が異なる
a.andThen(b)の場合
aが先に実行され、その後(and then)bが実行される。
a.compose(b)の場合
逆順になることに注意。