多分こんな感じ！Java8 ラムダ式 超ざっくり！

#なんの記事？
仕事中暇だったので、java8から追加された**ラムダ式**について調べた。
そのイメージでまとめた記事。

#記事の対象者は誰？
Javaの基本は抑えたぜ！
ラムダ式？ネットで検索しても詳しすぎてわかんねー(^q^)
って人向け。

#ラムダ式ってなんなん？
ラムダ式は、JDK1.8で導入された構文。
なんか最近見る、e->System.out.println(e.toString())とか。
関数型インターフェースってやつに代入できる物。

##メリットなんなの？
別にラムダ式を覚えたからと言って、すごいアルゴリズムがかけたり、モテたりするわけではない。
ただ、ドヤ顔はできるかも？
私が感じたラムダ式のメリットは、コードを短くかけるなーというところ。
あと、後々の話になるが関数型インターフェイス簡単に作れるわーってところ。
例えば、Runnableインターフェイスを実装する場合。
今までの場合、匿名クラスを使用すると・・・。

```java:MyThread01.java
public class MyThread {
	Thread thread;
	public MyThread(){
		thread = new Thread(new Runnable(){
			@Override
			public void run() {
				System.out.println("(/・ω・)/私です。");
			}
		});
	}
}
```

ラムダ式を使用すると・・・。

```java:MyThread02.java
public class MyThread {
	Thread thread;
	public MyThread(){
		thread = new Thread(()->System.out.println("(/・ω・)/私です。"));
	}
}
```

と、短くなる。うれしくないですか？

###補足
多分、私みたいに、適当にJavaの学習をしていると、「匿名クラス？なにそれ？しらねーよ」となると思う。
匿名クラスの説明は省いて、匿名クラスを使用しないで書いたコードが下のやつになるっぽ。

```java:MyThread03.java
public class MyThread {
	Thread thread;
	public MyThread(){
		thread = new Thread(new MyRunnable());
	}
	
	private class MyRunnable implements Runnable{
		@Override
		public void run() {
			System.out.println("(/・ω・)/私です。");
		}
	}
}
```
「匿名クラス」を超大雑把に説明すると、名前を付けずにクラスを宣言するやつ。
MyThread01.javaでは、MyThread03.javaみたいに、MyRunnableって名前のクラスがないでしょ？
匿名クラスだからだよ！

##ラムダ式の説明。
匿名クラスで実装したものと、ラムダ式で実装したものとの対応を可視化してみた。
私のイメージはこう！
![image01.png](https://qiita-image-store.s3.amazonaws.com/0/118314/512f0994-9cbc-fec7-d844-276a91127d72.png)

すごい大雑把ですね！
ところで、青の部分は何なの？って疑問になりませんか？
青の部分は、**引数**ですね！
Runnableインターフェイスは引数がないから分かりづらいですね！
引数がある自作インターフェイスで見てみますか！

先ほど同様、匿名クラスを使用した場合・・・。

```java:MyTestClass01.java
public class MyTestClass {
	
	public MyTestClass(){
		new Watashidesu(new MyTestInterface() {
			@Override
			public void watashidesuPrint(String str) {
				System.out.println(str+"私です！");
			}
		});
	}
	
	private class Watashidesu{
		String str ="(/・ω・)/";
		public Watashidesu(MyTestInterface mti) {
			mti.watashidesuPrint(str);
		}
	}
	private interface MyTestInterface{
		public void watashidesuPrint(String str);
	}
}
```

ラムダ式を利用した場合・・・。

```java:MyTestClass02.java
public class MyTestClass {
	
	public MyTestClass(){
		new Watashidesu((e)->System.out.println(e+"私です"));
	}
	
	private class Watashidesu{
		String str ="(/・ω・)/";
		public Watashidesu(MyTestInterface mti) {
			mti.watashidesuPrint(str);
		}
	}
	private interface MyTestInterface{
		public void watashidesuPrint(String str);
	}
}
```

ちょっと、インターフェイスとインターフェイスを利用したクラスを作成したため、可読性が悪くなりましたね！

public MyTestClass()の部分だけを見てください！
先ほど青色で囲んだ部分に違いがありますね！
匿名クラスのほうには、【String str】が！
ラムダ式には【e】が入っています！
つまりラムダ式のeは、String型のstrを示しているんです(*'ω'*)
型宣言されていませんが、それは、なんか上手くやってくれます。
ちなみに、(e)を(String e)に変えても問題はありませんよ。
なんか型宣言しないと気持ちが悪いという方は、宣言しましょう。
明記していてくれたほうが、読む側からすれば、いいかもですね。
あっ！あと、ラムダ式のeは、変数名の規約を守れば何でもおｋです！
普通は短くするっぽいです。（ラムダ式内でしか使われないから？）

##ラムダ式の利用どころ
いままでのサンプルを見ていると、インターフェイスの代わりにラムダ式を入れるって感じでしたね。
そう！ラムダ式の利用どころは、インターフェイスの変数に代入するときなのです！
つまり！

```java:
関数型インターフェイス に ラムダ式　を代入
(例)
Runnable r に ()=>{}を代入！
```

多分、私のように適当にJavaを学んだ初心者は、インターフェイスと聞いて、「implementsの後ろにつくあれかー」「とりあえずRunnableをimplements！」、くらいの知識だと思います。コードを書いていくうちにインターフェイスの便利さに気づいてくると思います。「デザインパターン」で検索することをお勧めしますよ。

また、ラムダ式が代入できるインターフェイスは関数型インターフェイスのみです。
関数型インターフェイスってなんやねんってなるとおもいますが、そんな難しいものではありません。
関数型インターフェイスもインターフェイスの一部なのですが、ちょっとだけ制約があります。
とりあえず、Runnableのapiをのぞいてみましょう。
API : [Runnableインターフェイス](https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Runnable.html)

抽象メソッドを見てください！
![image01.png](https://qiita-image-store.s3.amazonaws.com/0/118314/1c20ee5f-49a3-7674-5c49-2a7bb027b923.png)

はい！抽象メソッドが**一つだけ**ですね！
そうです！抽象メソッドが一つだけのインターフェイスが関数型インターフェイスなのです！
こういうやつは、上記みたいにラムダ式で代入できます。
ちなみに、以下のインターフェイスも関数型インターフェイス！
API : [Comparableインターフェイス](http://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html)
API : [BiFunctionインターフェイス](http://docs.oracle.com/javase/8/docs/api/java/util/function/BiFunction.html)
API : [Functionインターフェイス](http://docs.oracle.com/javase/8/docs/api/java/util/function/Function.html)

逆にこういうやつは関数型インターフェイスではありません。
API : [Listインターフェイス](https://docs.oracle.com/javase/jp/8/docs/api/java/util/List.html)
よって、ラムダ式で代入できません！

###補足
基本的に抽象メソッドは１つですが、たまに、複数個存在するのに関数型インターフェイスがある場合があります。
Objectクラスにあるpublicメソッドがインターフェース内に抽象メソッドとして定義されている場合、複数個存在します。
アノテーションFunctionalInterfaceがついていれば、関数型インターフェイスで間違いありません。
![image01.png](https://qiita-image-store.s3.amazonaws.com/0/118314/35fb1e9c-ecea-3080-d976-d72ccd2e61e3.png)


##まとめ
今回は、ラムダ式の記述法とか関数型インターフェイスの説明とかでした。
多分最初はラムダ式を書くことに抵抗を感じると思いますが、使っていくうちに慣れてきます。
「()->」を何度も書くといいかもですね！コードは見るだけでなくて書くことで理解が深まると思います。
ラムダ式とかを多用するのはStream関連だと思いますので、そのうち、それについてもザックリまとめます。
間違い・わからない所があれば、コメントください。
以上、ありがとうございました。