1. xrdnk

    Posted

    xrdnk
Changes in title
+[Java] ラムダ式入門
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,132 @@
+# 緒言
+Javaでスレッドを実行するためには,Threadクラスを継承したサブクラスを用いる方法と,
+Runnableインタフェースを実装したサブクラスを用いる方法があります.
+今回,ラムダ式の簡易的な説明のために後者を例にします.
+
+```java:Function.java
+public class Function implements Runnable{
+ @Override
+ public void run() {
+ // スレッドで処理する内容
+ System.out.println("hello!");
+ }
+}
+```
+
+```java:Main.java
+public class Main {
+ public static void main(String[] args) {
+ Thread thread = new Thread(new Function());
+ thread.start();
+ System.out.println("finish!");
+ }
+}
+```
+出力はこんな感じになると思います.
+
+```
+finish!
+hello!
+```
+ThreadクラスとRunnableインタフェースの関係は
+GoFデザインパターンのStrategyパターン設計が使われています.
+Strategyパターンは大まかにいえば「付け替えできるアルゴリズムを実現する」設計で,
+もともと1つだったクラスを処理の全体の流れを担当するクラスと,
+具体的なアルゴリズムを担当するクラスに分けて考えます.
+Strategyパターンを使うことで,使う側(Threadクラス)と
+使われる側(Runnableインタフェースを実現したクラス)を
+直接関係せずに済むため,あとから付け替えできるアルゴリズム実現することができます.
+(Strategyパターンを詳しく!という方は[こちら](https://www.techscore.com/tech/DesignPattern/Strategy.html/)を見ると良いかも)
+![UML2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156186/843a67b9-d6a5-ce61-ebae-6232d69c2aa6.png)
+しかしながら,インタフェースを実現したクラスには複雑なもの(UML図のFunctionHardクラス)と
+簡単なコードで済むクラス(UML図のFunctionEasyクラス)のようなものがあります.
+
+簡単なコードで済むのに,逐一新しいクラスを
+定義しなくてはならないのめんどくないですか?ということです.
+
+# ラムダ式の効力
+緒言で提示した問題点を解決するために,Java SE8から導入されたラムダ式を利用します.
+以下のコードはFunctionEasyクラスを作る代わりにラムダ式に置換したものです.
+
+```java:Lambda.java
+public class Lambda {
+ public static void main(String[] args) {
+ Runnable r = () -> System.out.println("hello!");
+ Thread thread = new Thread(r);
+ thread.start();
+ System.out.println("finish!");
+ }
+}
+```
+このように1行で済みます.スッキリ!
+ラムダ式は「関数型インタフェースをインスタンス化するときに
+めんどい記述しなくても済むような記法」と思えばよいです.
+
+実装が必要なメソッドを1つだけ持つインタフェースを「関数型インタフェース」や
+「SAM(Single Abstarct Method)インタフェース」と呼んだりします.
+
+SAMということからわかる通り,抽象メソッドを1つだけ持つため,
+ラムダ式がどのメソッドを実装するのか?引数と戻り値はどうなのか?
+推論が可能になります.逐一メソッド名を決める必要がないです.
+インタフェースを実現したクラスを用意せずに,ポリモーフィズムを実現できます.
+
+# 匿名クラスとラムダ式
+Java8以前は匿名クラスで実現されていました.
+匿名クラスは無名クラスとも呼ばれることがあります.
+
+```java
+
+ Runnable r = new Runnable() {
+ @Override
+ public void run() {
+ System.out.println("hello!");
+ }
+ }
+```
+長くて可読性が悪いですね.ほとんど誰も使わない状態になりました.
+そこでラムダ式が登場し,これをもっと簡単に記述できるようになります.
+
+```java
+ Runnable r = () -> {
+ System.out.println("hello!");
+ }
+```
+
+ラムダ式の宣言は,以下のように引数の変数宣言と処理ブロックで構成されます.
+
+```
+     { 引数 } -> { 処理 };
+```
+「->」をアロー演算子と呼びます.処理ブロックの最後にセミコロンをつけるの忘れずに.
+
+# ラムダ式省略記法
+ラムダ式では省略できるものがあります.
+以下の原型を例にたどってみましょう.
+
+```java:原型
+
+ Sample sample = (String a) -> { System.out.println(a);};
+```
+引数が**1つのときだけ**の場合,カッコ「()」を省略できます.
+また,引数の型は型推論できるため,省略することができます.
+
+
+```java:省略記法1
+ Sample sample = a -> { System.out.println(a);};
+```
+
+また,メソッド本体が1行の場合は,中カッコ「{}」と文末のセミコロン「;」を省略できます.
+return文の場合はreturnも省略できます.
+
+```java:省略記法2
+ Sample sample = a -> System.out.println(a);
+```
+
+さらに,引数が推論できる場合,メソッド呼び出しは
+ クラス名::メソッド名
+ オブジェクト名::メソッド名
+のように省略することができてしまいます.
+
+```java:省略記法3
+ Sample sample = System.out::println;
+```