lambda方法的引用與構造方法引用


方法的引用

/**
 * @auther hhh
 * @date 2018/12/29 22:37
 * @description
 */
public class ObjectMethodUse {
    /**
     * 對象方法的引用(有限制條件)
     *      抽象方法的第一個參數類型剛好是實例方法的類型(函數式接口的抽象方法必須要有輸入參數),抽象方法剩余
     *      的參數恰好可以當做實例方法的參數。如果函數式接口的實現能由上面說的實例方法調用來實現的話,
     *      那么就可以使用對象方法的引用(兩個條件都要滿足)
     * 語法:
     *      類名::instMethod
     */
    public void notUseObjectMethod(){
        //不能使用對象方法引用,因為其沒有輸入參數
        //比如如下函數式接口
        Runnable r = ()->{};
        Closeable c = () ->{};
        Supplier<String> s = ()->" ";
    }
    public static void main(String[] args) {
        //抽象方法的類型恰好是實例方法的類型
        //參數巧合是Too類型,調用的方法也是too的方法(Too too 與 new Too()是同種類型)
        //剩余的參數恰好可以當做實例方法的參數(Consumer<T>函數式接口沒有返回值,Too中的foo也沒有返回值)
        Consumer<Too> consumer = (Too too) -> new Too().foo();
        //可以使用對象方法引用
        Consumer<Too> consumer1 = Too::foo;

        consumer.accept(new Too());//invoke method
        consumer1.accept(new Too());//invoke method
        //不能轉化為對象方法引用,不滿足抽象方法的類型恰好是實例方法的類型
        Consumer<Too> consumer2 = (Too too) -> new Too1().foo();

        BiConsumer<Too1,String> biConsumer = (Too1 too,String s) -> new Too1().fun(s);
        BiConsumer<Too1,String> biConsumer1 = Too1::fun;
        biConsumer.accept(new Too1(),"輸入參數,調用方法");
        biConsumer1.accept(new Too1(),"輸入參數,調用方法");

        BiFunction<Prod,String,Integer> biFunction = (Prod s,String s1)->new Prod().fun(s1);
        //實例方法引用
        BiFunction<Prod,String,Integer> biFunction1 = Prod::fun;
        System.out.println(biFunction.apply(new Prod(),"12345"));//5
        System.out.println(biFunction1.apply(new Prod(),"12345"));//5

        //使用自定義函數式接口(有參數,且第一個參數類型為實例方法的類型)
        Execute2<Prod,String,String> execute2 = ( Prod,name,size) -> new Prod().fun2(name,size);
        Execute2<Prod,String,String> e= Prod::fun2;
    }
}
class Prod{
    Integer fun(String s){
        return s.length();
    }
    void fun2(String s,String s1){ }
}
//不符合使用對象方法引用,第一個參數需要是自定義的參數類型 T,不能是JDK自帶的對象類型
@FunctionalInterface
interface Execute1{
    void run(String name,String size);
}
//修改成這樣就可以了
@FunctionalInterface
interface Execute2<T,R,U>{
    void run(T t,R name, U size);
}
class Too{
    void foo(){
        System.out.println("invoke method");
    };
}
class Too1{
    void foo(){
        System.out.println("invoke method");
    };
    void fun(String s){
        System.out.println(s);
    }
}

構造方法的引用

/**
 * @auther hhh
 * @date 2018/12/30 11:19
 * @description 構造方法引用
 */
public class ConstructMethodUse {
    /**
     * 如果函數式接口的實現恰好可以通過調用一個類的構造方法來實現,那么就
     * 可以使用構造方法引用
     * 語法:
     *      類名::new
     */
    public static void main(String[] args) {
        //調用Person 無參構造函數
        Supplier<Person> personSupplier = ()->new Person();
        //由Supplier<Person> 可以推斷出Person::new  中Person 的類型
        Supplier<Person> personSupplier1 = Person::new;
        personSupplier.get();//invoke person construct
        personSupplier1.get();//invoke person construct

        //需要有無參構造函數
        Supplier<List<String>> supplier = ArrayList::new;
        Supplier<Thread> threadSupplier = Thread::new;

        //有參構造函數
        Consumer<Integer> c1 = (i)->new Student(i);
        Consumer<Integer> c2 = Student::new;
        c1.accept(1);//有參構造
        c2.accept(1);//有參構造
        Function<String,Integer> function = s -> s.length();
        Function<String,Integer> function1 = String::length;
        //第一個參數String Student的參數類型,第一個參數是new Student實例的參數
        Function<String,Student> function2 = Student::new;//有參構造String
    }
}
class Person{
    public Person() {
        System.out.println("invoke person construct");
    }
}
class Student{
    public Student(int i) {
        System.out.println("有參構造");
    }
    public Student(String s) {
        System.out.println("有參構造String");
    }
    public Student() {
        System.out.println("無參構造");
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM