JAva 8-Lambda式の構成と使用

5451 ワード

前の文章にはLambda式の姿が何度も現れており、その簡潔さと柔軟性は読者も感じているはずだと信じています.ではLambda式はいったい何なのでしょうか.その文法は何ですか.何から構成されていますか?Lambda式をどのように使用し、どこで使用すればいいですか?この文章はこれらの問題を解く.
Lambda式は何ですか?
Lambda式は、名前はありませんが、パラメータリスト、関数本体、戻りタイプがあり、放出可能な例外リストがある可能性があります.
  • 匿名--私たちが匿名と言ったのは、普通の方法のように明確な名前がないからです.書くことが少なくて考えているからです.
  • 関数--Lambda関数はメソッドのように特定のクラスに属していないため、関数と呼ばれています.ただし、方法と同様に、Lambdaにはパラメータリスト、関数本体、戻りタイプがあり、放出可能な例外リストもある可能性があります.
  • 転送-Lambda式は、パラメータとしてメソッドに渡すか、変数に格納することができる.
  • は簡潔です.匿名クラスのようにテンプレートコードを多く書く必要はありません.

  • Lambda式の構文と構成
    Lambda式は、パラメータ、矢印、ボディで構成されています.次の図を示します.
  • パラメータのリスト--ここではComparatorのcomparareメソッドのパラメータ、2つのAppleを採用しています.
  • 矢印-矢印->パラメータリストをLambda本体から分離します.
  • Lambda本体-2つのAppleの重量を比較します.式はLambdaの戻り値です.

  • したがって,Lambda式の基本構文は(parameters) -> expressionとまとめることができる. または  (parameters) -> { statements; }
    上の構文と比較して、次の表に、一般的なLambda式をいくつか示します.
    使用例
    Lambdaの例
    ブール式
    (List list) -> list.isEmpty()
    オブジェクトの作成
    () -> new Apple(10)
    一つの対象を消費する
    (Apple a) -> {System.out.println(a.getWeight());}
    オブジェクトからの選択/抽出
    (String s) -> s.length()
    2つの値を結合
    (int a, int b) -> a * b
    2つのオブジェクトの比較
    (Apple a1, Apple a2) ->a1.getWeight().compareTo(a2.getWeight())
    Lambda式の使用
    前の文章の中でそのリンゴを濾過する方法、私達はLambdaの表現式で実現したのは以下の通りです:
     
  • List greenApples = filter(inventory, (Apple a) -> "green".equals(a.getColor()));

  • では、なぜこのように使えるのでしょうか.filterメソッドの2番目のパラメータは、実際には関数インタフェースPredicateであり、その定義は以下の通りである.
     
  • public interface Predicate{
  • boolean test (T t);
  • }

  • 関数インタフェースとは、抽象的なメソッドを1つだけ定義するインタフェースです.
    実際にはjava 8以前に、次の関数インタフェースに触れたことがあります.
     
  • //java.util.Comparator
  • public interface Comparator {
  • int compare(T o1, T o2);
  • }
  • //java.lang.Runnable
  • public interface Runnable{
  • void run();
  • }
  • //java.awt.event.ActionListener
  • public interface ActionListener extends EventListener{
  • void actionPerformed(ActionEvent e);
  • }
  • //java.util.concurrent.Callable
  • public interface Callable{
  • V call();
  • }
  • //java.security.PrivilegedAction
  • public interface PrivilegedAction{
  • V run();
  • }
  • Predicateはjava 8で定義新しい関数インタフェースである.
    Lambda式は、関数式インタフェース(Lambda式自体が関数式インタフェースの一例である)をインラインで実現することを可能にする.
    次のように、関数インタフェースでrunnableのエンティティを匿名クラスで渡すこともできます.それらの実装効果は同じですが、匿名クラスの方が煩わしいだけです.
     
  • // Lambda runnable
  • Runnable r1 = () -> System.out.println("Hello World 1");
  • // , runnable
  • Runnable r2 = new Runnable(){
  • public void run(){
  • System.out.println("Hello World 2");
  • }
  • };
  • public static void process(Runnable r){
  • r.run();
  • }
  • process(r1);
  • process(r2);
  • // Lambda
  • process(() -> System.out.println("Hello World 3"));

  • 上のコードから分かるように、Lambda式は変数に値を与えることもできるし、パラメータとして関数式インタフェースをパラメータとする方法に直接伝達することもできる.Lambda式の署名は関数式インタフェースの抽象的な方法と同様であり、この抽象的な方法は関数記述子とも呼ばれる.JAvaコンパイラは、コンテキストに基づいて関数記述子をマッチングLambda式が正当か否かを判断する.
    Lambda式のオービット実行モードへの応用
    一般的に、ループ実行モード(execute around)とは、コード実行の先頭と末尾がテンプレートコードであることを意味し、本当に重要なコードは中間部分で実行される.例えば、ファイル処理:まずファイルを開き、それからファイルを処理し、最後にリソースを解放する.ここで、ファイルを開くのではなく、ファイルの処理に重点を置く.
    ファイルの処理は、需要によって異なるため、Lambda式は実行モードを囲むコード開発に特に適しており、ファイルを開くこととリソースを解放することという変わらないテンプレートコードが方法内に書かれており、異なる需要に対応する異なる行為がLambdaの形で伝達されている.
    コードは次のとおりです.
     
  • //
  • @FunctionalInterface
  • public interface BufferedReaderProcessor {
  • String process(BufferedReader b) throws IOException;
  • }
  • // ( )
  • public static String processFile(BufferedReaderProcessor p) throws IOException {
  • try (BufferedReader br = new BufferedReader(new FileReader("data.txt"))) {
  • return p.process(br);
  • }
  • }
  •  
  • // Lambda:
  • String oneLine = processFile((BufferedReader br) -> br.readLine());
  •  
  • // Lambda:
  • String twoLines = processFile((BufferedReader br) -> br.readLine() + br.readLine());