ブログをはじめてみようか(ラムダ式)

お初にお目にかかります。

エンジニアおじさんの mp_hsk です。

 

この度2年ぶり2度目の転職をすることになったのですが

どうも現職でだらけすぎたせいか、最近勘が鈍ってる気がしてます。

 

そこで、勘を取り戻すための勉強結果のアウトプットとしてブログを書いてみることにしました。(いわゆる技術ブログもどきを作ってみたくなったのございます)

 

 本日のテーマは

ラムダ式

おじさんは1.5, 1.6くらいのレガシーなJavaが長いけど、

Java 8 以降とか C#とかを少しかっこよく書きたいので復習をば。

ラムダ式ってなんぞ?

おじさんの理解としては(少なくともJava,C#における)ラムダ式

・デリゲートデザインパターンを簡単に書く構文

って感じだと思う。

デリゲートデザインパターンってのは、要は外から処理のブロック(関数)を差し込むっていう手法。

では具体的に

デリゲートってこんな感じ

Listから特定の条件に合致する値だけを取り出す処理を考える

条件は A, Bの2通りあるとすると普通だと

public class ArrayFilter{

    // フィルター結果を表示するだけだよん

 public static void main(String args){

          List<Integer> target = new ArrayList<Integer>();

         // 配列の値設定は省略

          // リスト内容を表示するメソッド(実装は割愛)

         printist(fillA(target));

         printist(fillB(target));
    }

 

    public static List<Integer> fillA(List<integer> list){

          List<Integer> res = new ArrayList<>

   for(Integer i : list){

               if(条件A)res.add(i);

           }

    }

   public static List<Integer> fillB(List<Integer> list){

          List<Integer> res = new ArrayList<>

   for(Integer i : list){

               if(条件B)res.add(i);

           }

    }

}

っていう感じのクラスを作る。けどよく見ると、ifの条件判定以外は処理同じじゃん!

ってことでこの部分をさぼるためにデリゲートを使う。

public class ArrayFilter{

    // フィルター結果を表示するだけだよん

 public static void main(String args){

          List<Integer> target = new ArrayList<Integer>();

         // 配列の値設定は省略

          // リスト内容を表示するメソッド(実装は割愛)

         printist(fill(target, new A()));

         printist(fill(target, new B()));
    }

    public static List<Integer> fill(List<integer> list ,Condition c){

          List<Integer> res = new ArrayList<>

   for(Integer i : list){

               if(c.isMatch(i))res.add(i);

           }

    }

}

// 条件の定義だけ別だしして型を定義、こいつがJavaでのデリゲート

//(関数インタフェースというらしい)

@FuctionalInterface

 public interface Condition{

    public boolean isMatch(Integer i);

 }

 // 条件A

public class A implement Condition{

    public boolean isMatch(Integer i){

          return 条件A;

    }

// 条件B

public class B implement Condition{

    public boolean isMatch(Integer i){

          return 条件B;

    }

こんな感じで書くことで、同じような処理をやっているところはなくなり、プログラムがなんとなくすっきりした!

でも、ぱっと見最初よりコード量多くなってね?

そこでラムダ式

上のプログラムをラムダ式で書くと

 

public class ArrayFilter{

    // フィルター結果を表示するだけだよん

 public static void main(String[] args){

          List<Integer> target = new ArrayList<Integer>();

         // 配列の値設定は省略

          // リスト内容を表示するメソッド(実装は割愛)

         // ラムダ式で直接条件Aと条件Bを差し込んじゃう

         printist(fill(target, (Integer i)->{return 条件A;});

         printist(fill(target, (Integer i)->{return 条件B;});
    }

    public static List<Integer> fill(List<integer> list ,Condition c){

          List<Integer> res = new ArrayList<>

   for(Integer i : list){

               if(c.isMatch(i))res.add(i);

           }

    }

}

// 条件の定義だけ別だしして型を定義、こいつがJavaでのデリゲート

//(関数インタフェースというらしい)

@FuctionalInterface

 public interface Condition{

    public boolean isMatch(Integer i);

 }

これで、見た目のコード量も減ってハッピー。

さらに、フィルターの条件なんてしょっちゅう変わりそうなものをイチイチ定義しなくても使えてさらにハッピー。というのがラムダ式である。

 

まとめ

ラムダ式は、要はデリゲートデザインパターンを短く書くための構文ということで、一旦はよさそう。

例ではわかりやすさのために適当な処理にしたけど、現場では主にイベントハンドラにイベント処理を設定するために使われていることが多いので、気になる人はググってね

 

参考リンク

Qiitaにいい記事があったので乗っけておこう

関数型プログラミングって何、ラムダってなんだよ

自分もお世話になっている技術メモの Hishidamaさんも関数インタフェースとラムダ式について書いてる記事もあった。

Java関数型インターフェースメモ(Hishidama's Java8 Functional Interface Memo)

Javaラムダ式メモ(Hishidama's Java8 Lambda Expression Memo)

 

ツッコミあればお待ちしてます