読者です 読者をやめる 読者になる 読者になる

Java8から追加されたラムダ式についてまとめてみた。

Java8から追加されたラムダ式に触れる機会が増えてきたので、ここらへんで自分の知識をまとめておきたいと思う。

まずラムダ式とはなにか。関数型インターフェース(1つのインターフェースに実装が必要なメソッドを1つだけ持つインターフェース)に対して、以下のような形式で記述する文法である。

(引数) -> {処理};


では、実際にどのようになるか見てみよう。まずはjava.util.function.Functionインタフェースに対して、ラムダ式を使わずに匿名クラスで記述した場合。

	public void testMethod() {
		Function<Integer, Double> function = new Function<Integer, Double>() {
			@Override
			public Double apply(Integer t) {
				return (double) t / 2;
			}
		};
		System.out.println(function.apply(1));
	}


では、上記をラムダ式で記述するとどのようになるか。

	public void testMethod() {
		Function<Integer, Double> function = (Integer t) -> {
			return (double) t / 2;
		};
		System.out.println(function.apply(1));
	}

慣れないと分かりにくいが、匿名クラスの作成やメソッド部分が省略され、ずいぶん記述量が減った。


ここから若干、駆け足で説明したいと思おう。まずは引数の型は定義されているため、記述を省略できる。(ここではジェネリックス型なので左辺で定義されている。ジェネリックス型以外であればインタフェースに定義済みである。)

	public void testMethod() {
		Function<Integer, Double> function = (t) -> {
			return (double) t / 2;
		};
		System.out.println(function.apply(1));
	}


さらに引数が一つであれば括弧()が省略できる。

	public void testMethod() {
		Function<Integer, Double> function = t -> {
			return (double) t / 2;
		};
		System.out.println(function.apply(1));
	}


また戻り値が一つであれば return を省略できる。

	public void testMethod() {
		Function<Integer, Double> function = t -> (double) t / 2;
		System.out.println(function.apply(1));
	}

最初の匿名クラスの場合と比較してみてほしい。たった一行でインターフェースの実装が完了してしまった!!

これがラムダ式の力である。


もちろん慣れるまで意味を把握しにくいかもしれないが、この記述量の削減には素晴らしいものがある!
それにJava8から追加された「Stream API」ではラムダ式が多用されるため、
ぜひとも早く慣れて使いこなせるようになっておいたほうがいい。


最後にいくつか補足を付け加える。

まずは引数がない場合、どのようになるか。答えは ()-> {処理}; となる。
ここではjava.util.function.Supplierについて例を記載する。

	public void testMethod_Supplier() {
		Supplier<String> supplier = () -> "supplier";
                // supplierと表示。
		System.out.println(supplier.get());
	}

またメソッド参照ができるので、このような記載も可能。
ここではjava.util.function.Consumerについて例を記載する。

	public void testMethod() {
		Consumer<String> consumer = System.out::println;
                // consumerと表示。
		consumer.accept("consumer");
	}