Java 8のLambda式を深く理解する

59486 ワード

微信公衆番号:朱小猿山は土を辞さないので、その高さになることができます.海は水を辞さないから、その深さになることができる!この文章があなたに役に立つと思ったら、転送してください[^1]
文書ディレクトリ
  • Java 8
  • を深く理解する
  • Lambdaの基本構文
  • 関数インタフェースのインスタンス
  • 関数インタフェース4種類
  • Lambda式の役割
  • Functionインタフェース
  • BiFunctionインタフェース
  • BinaryOperatorインタフェース
  • Consumerインタフェース
  • Predicateインタフェース
  • とStreamストリームを組み合わせた
  • Supplierインタフェース
  • MethodReference
  • 静的メソッド参照:ContainingClass::staticMethodName
  • 参照オブジェクトのインスタンスメソッド:containingObject::instanceMethodName
  • あるタイプの任意のオブジェクトを参照するインスタンスメソッド:ContainingType::methodName
  • 参照構築方法:ClassName::new
  • スーパークラスのインスタンスメソッド
  • を参照
  • 配列構成方法
  • 参照
  • Streamストリーム
  • 1. 流れの構成部分
  • 2.フロー操作の分類
  • Java 8を深く理解する
    Lambdaの基本構文
    (parm1,parm1,parm1) ->{
        
    };
    

    Lambda式構造
  • lambda式は、0個以上のパラメータ
  • を有することができる.
  • パラメータのタイプは、明確に宣言することも、コンテキストに基づいて
  • を推定することもできる.
  • すべてのパラメータはカッコ内に含める必要があります.パラメータ間はカンマで
  • 離れています.
  • 空カッコは、パラメータセットが空の
  • を表す.
  • パラメータが1つしかない場合、そのタイプが導出可能である場合、カッコ()は
  • を省略することができる.
  • Lambda式のマスターは、ゼロまたは複数の文
  • を含むことができる.
  • Lambda式のトピックに文が1つしかない場合、カッコ{}は省略できます.匿名関数の戻りタイプは、このマスター式と一致する
  • Lambda式のトピックに1つ以上の文が含まれている場合、式には再カッコ{}が含まれている必要があります.匿名関数の戻りタイプは、コードブロックの戻りタイプと一致し、なければ空の
  • に戻る.
    関数インタフェース
  • インタフェースには抽象的な方法が1つしかない
  • 関数インタフェースを宣言すると、インタフェースに@FunctionalInterface注記が追加され、コンパイラは関数インタフェースに従って
  • を検証する.
  • インタフェースに抽象メソッドが1つしかない場合、コンパイラはこのインタフェースを関数インタフェース
  • としてデフォルト化します.
  • インタフェースで定義されているメソッドが、カスタム親クラスObjectクラスのメソッドである場合、インタフェースは2つ以上のメソッドを持つことができる.インタフェースの実装クラスもObjectを継承するので、コンパイラはインタフェースに1つのメソッド
  • しかないと考えます.
    注意点
  • Python、JavaScriptなどの言語ではlambdaが関数、javaではlambdaがオブジェクト
  • java 8では、インタフェースには、default meathod
  • である必要がある具体的な方法の実装がある.
  • javaでは静的メソッド
  • を使用できます.
    関数インタフェースのインスタンス
    関数メソッドの宣言
  • は、lambda式を用いて、インタフェースインスタンス
    package funcationdemo;
    
    import java.util.Arrays;
    import java.util.List;
    
    /**
     *   :
     * lambda     
     *
     * @author zhusy
     * @create 2020-05-11 10:05
     */
    public class Test01 {
        public static void main(String[] args) {
            List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 7);
            MyInterface myInterface = i -> {
                return i;
            };
            list.forEach(i -> System.out.println(myInterface.printElement(i)));
    
        }
    }
    @FunctionalInterface
    interface MyInterface{
        Integer printElement(Integer i);
    }
    
    
  • を宣言する.
  • メソッド参照による宣言
    public class Test01 {
        public static void main(String[] args) {
            List<String> list2 = Arrays.asList("hello","world","hello world");
            list2.forEach(String::toUpperCase);
        }
    }
    
    
  • 構造方法による宣言
    package funcationdemo;
    
    /**
     *   :
     * lambda     
     *
     * @author zhusy
     * @create 2020-05-11 10:05
     */
    public class Test01 {
        public static void main(String[] args) {
            MyInterface myInterface = Person::new;
            System.out.println(myInterface.getPerson("  "));
        }
    }
    
    @FunctionalInterface
    interface MyInterface {
        Person getPerson(String name);
    }
    
    class Person {
        private String name;
    
        public Person(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "Person{" +
                "name='" + name + '\'' +
                '}';
        }
    }
    
    
    
  • 関数インタフェースの4種類
    関数インタフェース
    方法
    パラメータタイプ
    戻りタイプ
    さぎょう
    Consumerコンシューマインタフェース
    void accept(T t)
    T
    void
    Tタイプのパラメータを操作する
    Supplier供給型インタフェース
    T get()
    なし
    T
    操作データ、Tタイプの結果を返す
    Function関数型インタフェース
    R apply(T t)
    T
    R
    Tタイプパラメータを操作し、Rタイプの結果を返す
    Predicate断定型インタフェース
    boolean test(T t)
    T
    boolean
    Tタイプパラメータが制約を満たしているかどうかを決定し、boolean値を返します.
    Lambda式の役割
  • は、値
  • だけでなく、動作を伝達する.
  • 抽象階層を上げる
  • APIの再利用性がより良い
  • より柔軟な
  • Functionインタフェース
    関数式インタフェースでは,伝達値も行為の伝達も可能であり,方法の利用者に方法に必要な行為を伝達させ,方法自体がより抽象的な論理的実現を行うことができる.
    package funcationdemo;
    
    import java.util.function.Function;
    
    /**
     *   :
     * function     
     *
     * @author zhusy 2020-05-12 13:31
     *
     */
    public class FunctionTest {
        public static void main(String[] args) {
            FunctionTest functionTest = new FunctionTest();
            System.out.println(functionTest.compute(3, value -> value * value));
        }
    
        public int compute(int a, Function<Integer, Integer> function) {
            return function.apply(a);
        }
    }
    

    BiFunctionインタフェース
    package funcationdemo;
    
    import java.util.function.BiFunction;
    import java.util.function.Function;
    
    /****************************************
     *   :
     * BiFunction      
     *  Interface BiFunction
     *      T -           
     *      U -           
     *      R -        
     *
     *                      。
     *       Function            
     *
     *
     *
     * @author zhusy 2020-05-13 14:22
     ****************************************/
    public class BiFunctionTest {
        public static void main(String[] args) {
            BiFunctionTest test = new BiFunctionTest();
    //              
            System.out.println(test.compute(3, 4, Integer::sum));
    
    //        System.out.println(test.compute2(3, 4, Integer::sum, item -> item * item));
    //           
            System.out.println(test.compute2(3, 4, (num1, num2) -> num1 * num2, value -> value * value));
    
        }
    
        /**
         * public interface BiFunction {
         * 

    * R apply(T t, U u); *

    *

    * } */

    public int compute(int num1, int num2, BiFunction<Integer, Integer, Integer> function) { return function.apply(num1, num2); } /**** * default BiFunction andThen(Function super R, ? extends V> after) { * Objects.requireNonNull(after); * return (T t, U u) -> after.apply(apply(t, u)); * } * @param num1 * @param num2 * @param function ( ) * @param function2 * @return */ public int compute2(int num1, int num2, BiFunction<Integer, Integer, Integer> function, Function<Integer, Integer> function2) { return function.andThen(function2).apply(num1, num2); } }

    BinaryOperatorインタフェース
    package funcationdemo;
    
    import java.util.Comparator;
    import java.util.function.BinaryOperator;
    
    /**************************************************************
     *   :
     *    BinaryOperator
     *                    ,           。
     *                     
     *     BiFunction    
     *
     * @author zhusy 2020-05-13 14:31
     *
     **************************************************************/
    public class BinaryOperatorTest {
        public static void main(String[] args) {
            BinaryOperatorTest test = new BinaryOperatorTest();
            System.out.println(test.compute(3, 4, Integer::sum));
            System.out.println(test.minByComparator(5, 6, Comparator.comparingInt(num -> num)));
        }
    
        /****
         *
         *    BiFunction ,    apply()  
         *            
         *
         * public interface BinaryOperator extends BiFunction {
         *
         * }
         *
         *
         * @param num1
         * @param num2
         * @param function
         * @return
         */
        public int compute(int num1, int num2, BinaryOperator<Integer> function) {
            return function.apply(num1, num2);
        }
    
        /***
         *
         *     public static  BinaryOperator minBy(Comparator super T> comparator) {
         *         Objects.requireNonNull(comparator);
         *         return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;
         *     }
         *
         * @param num1     1
         * @param num2     2
         * @param comparator    
         * @return        
         */
    
        public int minByComparator(int num1, int num2, Comparator<Integer> comparator) {
            return BinaryOperator.minBy(comparator).apply(num1, num2);
        }
    }
    
    

    Consumerインタフェース
    package funcationdemo;
    
    import java.util.Arrays;
    import java.util.List;
    import java.util.Optional;
    import java.util.function.Consumer;
    
    /*********************************************************
     *   :
     * Consumer  
     *                     
     *
     *
     * @author zhusy 2020-05-12 14:12
     ********************************************************/
    public class ConsumerTest {
        public static void main(String[] args) {
            List<String> list = Arrays.asList("hello", "world", "hello world");
            list.forEach(str->{
                String strParam = str;
                Optional<String> optional = Optional.ofNullable(strParam);
                String rtn = optional.map(strParam1 -> strParam1.toUpperCase()).orElse("");
                System.out.println(rtn);
            });
    
        }
    }
    

    Predicateインタフェース
    Streamsストリームと組み合わせて使用
    package funcationdemo;
    
    import java.util.Arrays;
    import java.util.List;
    import java.util.Optional;
    import java.util.function.Consumer;
    import java.util.function.Function;
    import java.util.function.Predicate;
    
    /**************************************************************
     *   :
     *    Predicate
     *               
     *
     * @author zhusy 2020-05-13 15:40
     *
     **************************************************************/
    public class PredicateTest {
        public static void main(String[] args) {
            PredicateTest test = new PredicateTest();
            System.out.println(test.isTrueOfStr("hell0", str -> str.length() > 4));
            List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
    //      Predicate     
            Predicate<Integer> predicate = i -> i % 2 == 0;
    //       Optional      
            Function<Integer, Integer> function = integer -> {
                Optional<Integer> integerOptional = Optional.of(integer);
                Integer rtn = integerOptional.map(ele -> 2 * ele).get();
                return rtn;
            };
    //          
            Consumer<Integer> consumer = param -> {
                Optional<Integer> integer = Optional.ofNullable(param);
                Integer rtn = integer.map(function).get();
                System.out.println(rtn);
            };
            test.conditionFilter(list, predicate, consumer);
        }
    
        public boolean isTrueOfStr(String str, Predicate<String> funciton) {
            return funciton.test(str);
        }
    
        public void conditionFilter(List<Integer> list, Predicate<Integer> predicate, Consumer<Integer> consumer) {
            list.stream().filter(predicate).forEach(consumer);
        }
    }
    
    

    Supplierインタフェース
    package funcationdemo;
    
    import java.util.function.Supplier;
    
    /**************************************************************
     *   :
     *    Supplier
     *           ,                        
     *         ,      。             
     *
     *
     * @author zhusy 2020-05-13 16:04
     *
     **************************************************************/
    public class SupplierTest {
        public static void main(String[] args) {
            Supplier<String> supplier = String::new;
            String str = supplier.get();
            str = "hello world";
            System.out.println(str);
        }
    }
    
    

    MethodReference
    メソッドリファレンスは、クラスまたはインスタンスに直接アクセスするための既存のメソッドまたは構築メソッドです. は、互換性のある関数インタフェースからなるターゲットタイプコンテキストを必要とする.計算時にメソッドリファレンスは、関数インタフェースのインスタンスを作成します.
    静的メソッドの参照:ContainingClass::staticMethodName
    package methodreference;
    
    import java.util.Arrays;
    import java.util.List;
    
    /**************************************************************
     *   :
     *    MethodReference
     *        
     * @author zhusy 2020-05-13 16:43
     *
     **************************************************************/
    public class MethodReferenceTest {
    
        static void toUpperCaseByStr(String str) {
            System.out.println(str.toUpperCase());
        }
    
        public static void main(String[] args) {
            List<String> list = Arrays.asList("hello", "world", "hello world");
    //        ContainingClass::staticMethodName       
            list.forEach(MethodReferenceTest::toUpperCaseByStr);
        }
    }
    

    オブジェクトのインスタンスを参照する方法:containingObject::instanceMethodName
    package methodreference;
    
    import java.util.Arrays;
    import java.util.List;
    
    /**************************************************************
     *   :
     *    MethodReference
     *        
     * @author zhusy 2020-05-13 16:43
     *
     **************************************************************/
    public class MethodReferenceTest {
    
        void toUpperCaseByStr(String str) {
            System.out.println(str.toUpperCase());
        }
    
        public static void main(String[] args) {
            List<String> list = Arrays.asList("hello", "world", "hello world");
            //                 
            MethodReferenceTest test = new MethodReferenceTest();
            list.forEach(test::toUpperCaseByStr);
        }
    }
    

    任意のタイプのオブジェクトのインスタンスを参照する方法:ContainingType::methodName
    package methodreference;
    
    import java.util.Arrays;
    import java.util.List;
    import java.util.function.Consumer;
    
    /**************************************************************
     *   :
     *    MethodReference
     *        
     * @author zhusy 2020-05-13 16:43
     *
     **************************************************************/
    public class MethodReferenceTest{
    
        public static void main(String[] args) {
            /*                */
            List<String> list = Arrays.asList("hello", "world", "hello world");
            list.sort(String::compareTo);
            list.forEach(System.out::println);
        }
    }
    
    

    参照構築方法:ClassName::new
    package methodreference;
    
    import java.util.function.Supplier;
    
    /**************************************************************
     *   :
     *    MethodReference
     *        
     * @author zhusy 2020-05-13 16:43
     *
     **************************************************************/
    public class MethodReferenceTest{
    
        public MethodReferenceTest() {
        }
    
        public String getString(Supplier<String> supplier){
            return supplier.get() +"test";
        }
        public static void main(String[] args) {
            MethodReferenceTest test = new MethodReferenceTest();
            System.out.println(test.getString(String::new));
        }
    }
    
    

    スーパークラスのインスタンスメソッドリファレンス
    **構文形式の構成:super::methodName
    メソッドの名前はmethodNameで指定され、superを使用することでメソッドのスーパークラスバージョンを参照できます.
    thisポインタもキャプチャできます.this::equalsはlambda式x->thisに等価です.equals(x);
    配列構築メソッドリファレンス
    **構成構文形式:Type Name[]::new
    例:
    int[]::newは、配列の長さであるパラメータを含むコンストラクタ参照です.Lambda式x->new int[x]に等しい.
    intパラメータを受信する配列構造方法が仮想的に存在する
    ​ IntFunction arrayMaker =int[]::new;int[] array = arrayMaker.apply(10)/配列intの作成[10]
    ストリームストリーム
    1.流れの構成部分
  • ソース
  • 0個以上の中間動作
  • 終了操作
  • 2.フロー操作の分類
  • 不活性評価
  • はチェーン方式で呼び出すことができ、実際に呼び出すと
  • が実行される.
  • 早期評価
  • が呼び出されると計算結果
  • が開始する.

    以下は私の公式番号のQRコードの画像で、注目を歓迎します.