Lambada式のまとめ


前言
jdk 1.8の新しい特性として、8の標準ライブラリはlambda式を大量に使用し始めました.lambdaを勉強しない理由はありませんか.こんなに簡潔で、このようなさっぱりしたプログラミング方法は、勉強しないのがもったいないと思いませんか.
Lambdaすなわちλ,匿名関数という意味でjavaではlambda式は本質的に匿名の内部クラスを定義しているだけです.すなわち、匿名関数を定義しながら、匿名内部クラスを定義します.
1、匿名内部クラス->匿名関数
匿名の内部クラスで、インタフェースと抽象クラスを使用して、そのサブクラスまたは実装クラスオブジェクトを直接生成できます.
既存のインタフェースで、抽象的な方法があります.
public interface Ability {
    void doAbility(String token);
}

匿名の内部クラスを使用したい場合は、次のように、サブクラスまたはインプリメンテーションクラスを定義することなく、サブクラスオブジェクトまたはインプリメンテーションクラスオブジェクトを直接取得できます.
public class LOLHero  {
    public static void main(String[] args) {

        Ability ability = new Ability(){
            @Override
            public void doAbility(String token) {
                System.out.println("       ");
            }
        };

    }
}

ははは、次はlambdaで同じ効果を実現します.この例ではlambdaの本質が見えます.震えましょう.仲間たち:
public class LOLHero  {
    public static void main(String[] args) {
        Ability ability2 = (token)->{System.out.println("        ");};
    }
}

はい、あなたが見たと信じています.lambda式は匿名の内部クラスを表していますが、newのインタフェースや抽象クラスではなく、直接中の方法を定義しています.はい、匿名の方法で、匿名の内部クラスを表現しています.したがって,lambda式は匿名の内部クラスを用いた簡略化手法である.異なる点は、匿名内部クラスの使用範囲はインタフェースと抽象クラスでなければならず、インタフェースと抽象クラスにはn個の抽象メソッド+n個の具体的なメソッドがあり得るが、lambda式の適用範囲はインタフェースのみであり、インタフェース内には1個の抽象メソッド+n個の具体的なメソッドしかないことである.そう、この抽象的な方法はあなたが定義した匿名関数です.
2、lambdaの2種類の使用シーン
Lambda式の使用はjavaがコンテキスト文脈を推定することによってインタフェースタイプを得,インタフェースに抽象的な方法が1つしかないことを発見すればlambda式を使用することができる.
最初のシーン、パラメータの位置:
public class LOLHero  {
    public static void main(String[] args) {
        specialFuntion((token)->{
            System.out.println(token+":    。。。。。。");
        });
    }

    public static void specialFuntion(Ability ability){
        ability.doAbility("    ");
    }
}

JAvaは、パラメータのデータ型に基づいてlambda式を推定することができる.mainメソッドではspecialFunctionメソッドを呼び出すときに匿名の内部クラスを入力します.このインタフェースには抽象メソッドが1つしかないことに気づきました.そのため、lambda式を直接使用して匿名関数を直接定義すると、この匿名の内部クラスを手に入れることができます.インタフェース名、インタフェース抽象メソッドのパラメータタイプ、javaは推定できます.記入する必要はありません.うん....もしかすると、文法糖...まぁ.はい、でも魔法のように面白いです.
実行結果:
    :    。。。。。。

2番目のシーンで、値の位置を返します.
public class LOLHero  {
    public static void main(String[] args) {
        Ability ability1 = getAbility();
    }

    public static Ability getAbility(){
        return (token)->{
            System.out.println(token+":    。。。。。。。。");
        };
    }
}

この場合、javaは戻り値のデータ型に基づいてlambda式を推定します.道理は同じです.javaはAbilityインタフェースを返すことを知っていますが、このインタフェースには抽象的な方法しかありません.そのため、ここではlambda式を使用して匿名の内部クラスを表すことができます.
3、lambdaの使用例
スレッド起動
public class LOLHero  {
    public static void main(String[] args) {
        ScheduledExecutorService es = Executors.newScheduledThreadPool(2);
        es.scheduleAtFixedRate(()->{
            System.out.println("    !");
        },0,2,TimeUnit.SECONDS);

    }
}

最初のパラメータはRnnableインタフェースで、このインタフェースには抽象的な方法が1つしかないので、ここではlambda式を使用できます.
ストリームオブジェクトの遍歴
機知に富んだあなたたちは、実際に集合を使用するときに、最もよく使われるときに各要素を反復し、各要素を操作することを知っています.コレクションのストリームオブジェクト+lambda式を使用すると、簡単にできます.
public class LOLHero  {
    public static void main(String[] args) {
        List heros = new ArrayList<>(Arrays.asList("  ","  ","   ","  ","  ","  "," "));
        heros.stream().forEach(x-> System.out.println(x));
    }
}

ここで、forEachメソッドのパラメータはConsumerインタフェースであり、彼は唯一の抽象メソッドaccept(T t)を持っており、ここでlambada式はConsumerインタフェースを実現した匿名の内部クラスである.遍歴結果:
  
  
   
  
  
  
 

機知に富んだあなたは、重複するデータをフィルタリングし、一定の条件のデータをフィルタリングしたいと思っています.以下のようにします.
public class LOLHero  {
    public static void main(String[] args) {
        List heros = new ArrayList<>(Arrays.asList("  ","  ","   ","  ","  ","  "," "));
        heros.stream().filter(n->n.length() > 1).distinct().forEach(n-> System.out.println(n));
    }
}

filterメソッドのパラメータはPredicateインタフェースであり、長さ>1の要素をフィルタする唯一の抽象メソッドtest(T t)があり、distinct()は重複要素をフィルタし、遍歴結果は以下の通りである.
  
  
   
  

ストリームオブジェクトの関数プログラミング
関数プログラミングの核心はmapが要素変換を行い、reduceが要素集約を行い、以下の通りである.
public class LOLHero  {
    public static void main(String[] args) {
        List heros = new ArrayList<>(Arrays.asList("  ","  ","   ","  ","  ","  "," "));
        Integer reduce = heros.stream().map((x) -> x.length()).reduce(0, (sum, x) -> sum + x);
        System.out.println(reduce);
    }
}

mapメソッドのパラメータはFunctionインタフェースであり、唯一の抽象メソッドapply(T t)があり、reduceメソッドの最初のパラメータは初期値であり、2番目のパラメータはインタフェースBinaryOperatorであり、唯一の抽象メソッドapply(T,U u)があり、reduceメソッドは前の要素の計算結果をsum位置(最初の初期値)に置き、次の要素をx位置に置いて集約操作を行う.この例では、mapは各要素をその長さに変換し、reduceでその総長を取得し、結果は以下の通りである.
14

次に、関数でプログラミングした例をいくつか示します.
public class LOLHero  {
    public static void main(String[] args) {
        List heros = new ArrayList<>(Arrays.asList("  ","  ","   ","  ","  ","  "," "));
        //              
        String s = heros.stream().map(x->x+1).collect(Collectors.joining(","));
        //         
        List list = heros.stream().map(x -> x + x).collect(Collectors.toList());
        //  int,long,double     ,       ,   ,   ,    ,    
        IntSummaryStatistics intSummaryStatistics = heros.stream().map(x -> x.length()).mapToInt(x -> x).summaryStatistics();
    }
}

まとめ
これだけ言っても、実はlambdaの本質は、冒頭で述べたように匿名の内部クラスを定義するだけで、この鍵をつかめば、lambdaを使うのは余裕があるのではないでしょうか.
JAva 8には、4つのコア関数インタフェース(関数インタフェース、すなわち抽象関数が1つしかないインタフェース)が追加されました.
Consumer :      (    )
         void accept(T t);
 Supplier :      (    )
         T get();
         
 Function :      (    )
        R apply(T t);
        
 Predicate :      (    )
        boolean test(T t);