Java知識點——方法引用

1. 方法引用

1.1 Lambda冗餘問題以及方法引用初識
package com.qfedu.d_methodreference;

/**
 * 函數式接口
 *
 * @author Anonymous
 */
@FunctionalInterface
interface PrintMethod {
    void print(String str);
}

/**
 * Lambda冗餘問題
 *
 * @author Anonymous 2020/3/12 15:53
 */
public class Demo1 {
    public static void main(String[] args) {
        /*
         使用Lambda表達式來展示字符串
         IDEA有一個提示,這裏可以繼續優化

         目標:
            testPrint方法,需要將String str交給 PrintMethod進行處理
            PrintMethod處理的方式是System.out.println

            PrintMethod是一個函數式接口,可以使用Lambda表達式完成代碼
            但是貌似和這個接口,這裏Lambda不夠接近目標

            明確:
                1. 我要用System.out對象
                2. 需要使用println方法
                3. 需要處理的數據是明確的
         */
        testPrint("鄭州加油!!!", str -> System.out.println(str));

        // 利用方法引用來處理當前代碼
        /*
        調用對象:
            System.out
        執行方法:
            println方法
        需要處理的數據(可推導,可省略)
            "中國加油!!!祖國萬歲!!!"
        ::
            Java中【方法引用】使用的運算符,標記
         */
        testPrint("中國加油!!!祖國萬歲!!!", System.out::println);
    }

    /**
     * 該方法是一個使用函數式接口作爲方法參數的一個方法
     *
     * @param str String類型的字符串
     * @param pm  PrintMethod函數式接口
     */
    public static void testPrint(String str, PrintMethod pm) {
        pm.print(str);
    }
}

1.2 方法引用小要求
 testPrint("鄭州加油!!!", str -> System.out.println(str));
 
 testPrint("鄭州加油!!!", System.out::println);
 
 1. 明確對象
 	對象 ==> 調用者
 	類對象,類名,super,this,構造方法,數組構造方法
 2. 明確的執行方法
 	該方法只有名字不需要顯式出現參數
 3. 需要處理的數據
 	【聯想,推導,省略】
 4. :: 方法引用格式
1.3 通過類對象來執行方法引用
1. 明確對象
	類對象
2. 明確執行的方法
	自定義
3. 處理的數據
	簡單要求爲String類型
package com.qfedu.e_objectmethodreference;

/**
 * 函數式接口
 *      明確約束方法
 *          方法類型是
 *              參數是String類型參數
 *              沒有返回值
 */
@FunctionalInterface
public interface Printable {
    void method(String str);
}

/**
 * 自定義類
 */
public class ObjectMethodReference {
    /**
     * ObjectMethodReference類內的【成員方法】
     *     1. 參數是String類型
     *     2. 沒有返回值
     * @param str 參數
     */
    public void print(String str) {

        System.out.println(str.toLowerCase());
    }

    /**
     * ObjectMethodReference類內的【成員方法】
     *     1. 參數是String類型
     *     2. 沒有返回值
     * @param str 參數
     */
    public void printSubstring(String str) {
        System.out.println(str.substring(3));
    }

    public void saolei() {
        System.out.println("無參數方法");
    }
}
​```

​```java
package com.qfedu.e_objectmethodreference;





/**
 * 類對象使用方法引用展示
 *
 * @author Anonymous 2020/3/12 16:18
 */
public class Demo2 {
    public static void main(String[] args) {
        /*
        test方法需要使用一個Printable接口,執行對應的print方法
        這裏需要引用ObjectMethodReference類對象對應的print方法,該方法有展示能力
         */
        ObjectMethodReference obj = new ObjectMethodReference();

        /*
        執行的對象:
            ObjectMethodReference的類對象
        明確執行的方法:
            print方法
        執行的目標:
            "ABCDE" 可省略,可推導
         */
        test(obj::printSubstring);
    }

    /**
     *
     * @param printable 函數式接口,約束的是方法類型
     */
    public static void test(Printable printable) {
        printable.method("ABCDE");
    }
}

​```

1.4 通過類名來執行方法引用
package com.qfedu.f_classmethodreference;

import java.util.List;

/**
 * 函數式接口
 */
@FunctionalInterface
public interface PrintList {
    /**
     * 方法參數爲List集合
     * 沒有返回值
     * @param list List集合
     */
    void print(List<?> list);
}
package com.qfedu.f_classmethodreference;

import java.util.List;

/**
 * 通過列明調用的靜態方法,演示類
 */
public class ClassMethodReference {
    /**
     * 該方法符合要求
     * 沒有返回值
     * @param list list集合
     */
    public static void showListInfo(List<?> list) {
        for (Object o : list) {
            System.out.println(o);
        }
    }
}
package com.qfedu.f_classmethodreference;

import java.util.ArrayList;

/**
 * 通過類名來執行方法引用
 *
 * @author Anonymous 2020/3/12 16:39
 */
public class Demo3 {
    public static void main(String[] args) {
        /*
         明確調用對象
            當前方法是一個靜態成員方法,需要通過類名調用
         明確調用方法
            showListInfo
         明確的數據
            ArrayList<String> list = new ArrayList<>();
            可省略,可推導
         */
        testClass(ClassMethodReference::showListInfo);


        /*
        Lambda表達式
         */
        testClass(list -> {
            for (Object o : list) {
                System.out.println(o);
            }
        });
    }

    /**
     * 利用了一個函數式接口作爲方法的參數
     *
     * @param printList 函數式接口
     */
    public static void testClass(PrintList printList) {
        ArrayList<String> list = new ArrayList<>();

        list.add("BMW");
        list.add("Audi");

        printList.print(list);
	}

}

1.5 通過super關鍵字執行方法引用
package com.qfedu.g_supermethodreference;

/**
 * @author Anonymous 2020/3/12 16:52
 */
public interface SaySomeThing {
    void say();
}
package com.qfedu.g_supermethodreference;

/**
 * @author Anonymous 2020/3/12 16:53
 */
public class Father {
    public void sayHello() {
        System.out.println("你好 Java");
    }
}
package com.qfedu.g_supermethodreference;

import java.util.Scanner;

/**
 * @author Anonymous 2020/3/12 16:53
 */
public class Son extends Father {

    public static void main(String[] args) {
        //lambda
        testSay(() -> System.out.println("你好"));

        new Son().sonMethod();
    }

    /**
     * 這裏的參數是一個函數式接口,這裏需要提供給一個符合要求的方法
     * @param sst 函數式接口參數
     */
    public static void testSay(SaySomeThing sst) {
        sst.say();
    }

    public void sonMethod() {
        /*
        父類中有一個無參數無返回值的sayHello
        滿足當前SaySomeThing函數式接口,方法要求

        執行的對象
            super關鍵字,因爲該方法在父類內
        執行的方法:
            sayHello
        無需參數
         */
        testSay(super::sayHello);
    }
}
1.6 通過this關鍵字執行方法引用
package com.qfedu.h_thismethodreference;

/**
 * @author Anonymous 2020/3/12 17:00
 */
public interface ORM {
    /**
     * int ==> String
     * @param i int類型
     * @return String類型
     */
    String toStringType(int i);
}
package com.qfedu.h_thismethodreference;

/**
 * @author Anonymous 2020/3/12 17:01
 */
public class ThisDemo {
    public void test() {
        String s = testThis(i -> i + ":");
        System.out.println(s);

        /*
        調用方法的對象
            this
        執行的方法:
            turn方法
        處理的數據
            10 (可省略,可聯想)
         */
        String s1 = testThis(this::turn);
    }

    public String turn(int i) {
        return i + ":字符串";
    }

    public static String testThis(ORM orm) {
        return orm.toStringType(10);
    }

    public static void main(String[] args) {
        new ThisDemo().test();
    }
}
1.7 類構造方法引用
package com.qfedu.a_methodreference;

/**
 * 函數式接口
 *
 * @author Anonymous 2020/3/13 9:56
 */
public interface PersonMethodReference {

    /**
     * 該方法是獲取Person類對象,形式參數是Stringname
     * @param name String類型
     * @return Person類對象
     */
    Person getPerosnObject(String name);
}
package com.qfedu.a_methodreference;

/**
 * Perosn類
 *
 * @author Anonymous 2020/3/13 9:56
 */
public class Person {
    private String name;

    public Person() {}

    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 + '\'' +
                '}';
    }
}
package com.qfedu.a_methodreference;

/**
 * 方法引用構造方法演示
 *
 * @author Anonymous 2020/3/13 9:54
 */
public class Demo1 {
    public static void main(String[] args) {
        /*
        這裏使用利用Lambda表達式完成對象創建
        這裏可以使用方法引用完成,引用的方法是Person類的構造方法
         */
        printPerson("騷磊", name -> new Person(name));

        /*
        Person::new
            Person是數據類型,是類名
            new 引用的關鍵字(方法)
                new --> 對應參數的構造方法
         */
        printPerson("航海中路彭于晏", Person::new);
    }

    /**
     * 方法參數使用到一個函數式接口的引用,這裏可以是引用Lambda表達式來完成
     *
     * @param name   String類型
     * @param method 函數式接口
     */
    public static void printPerson(String name, PersonMethodReference method) {
        System.out.println(method.getPerosnObject(name));
    }
}


1.8 數組創建方式引用
package com.qfedu.b_arrayConstructor;

/**
 * 函數式結構
 *
 * @author Anonymous 2020/3/13 10:07
 */
@FunctionalInterface
public interface ArrayConstructorReference {
    /**
     * 限制指定容量,返回int類型數組
     * @param capacity 要求數組的初始化容量
     * @return 返回一個int類型數組
     */
    public int[] createIntArray(int capacity);
}
package com.qfedu.b_arrayConstructor;

/**
 * 演示數組構造方式方法引用
 *
 * @author Anonymous 2020/3/13 10:08
 */
public class Demo1 {
    public static void main(String[] args) {
        /*
        利用Lambda表達式完成函數式接口使用,創建數組對象
         */
        int[] intArray = getIntArray(10, capacity -> new int[capacity]);
        System.out.println(intArray);
        /*
        數組構造方法方法引用
        明確數據類型
            int 類型數組
            [] 數組標記
            :: new 需要申請空間,創建對應的數組
         */
        int[] intArray1 = getIntArray(20, int[]::new);
        System.out.println(intArray1);
    }

    /**
     * 這裏是創建Int類型數組返回的方法
     *
     * @param capacity 指定的數組容量
     * @param ref      函數式接口
     * @return 指定容量的int類型數組
     */
    public static int[] getIntArray(int capacity, ArrayConstructorReference ref) {
        return ref.createIntArray(capacity);
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章