java學習筆記(12)——方法引用

public static void printString(PrintA p) {
        p.print("helloworld");
    }

    public static void main(String[] args) {
    //最繁雜寫法
        printString(new PrintA() {
            @Override
            public void print(String s) {
                System.out.println(s);
            }
        });
    //Lambda表達式的簡化版
        printString((s) -> System.out.println(s));
    //方法引用
        printString(System.out::println);

printString(System.out::println);
::
雙冒號爲引用運算符,所在表達式被稱爲方法引用
若是Lambda要表達的函數方案已經存在於某個方案語法的實現中,能夠用此法代替Lambda
image.png數組

image.png

注意:app

Lambda中傳遞的參數必定是方法引用中的那個方法能夠接收的類型,不然拋出異常

經過對象名引用成員方法

@FunctionalInterface
public interface PrintB {
    void print(String s);
}
public class MethodRerObject {
    public void printUpperCase(String str) {
        System.out.println(str.toUpperCase());
    }
}
public static void printString(PrintB p) {
        p.print("hellow");
    }
    public static void main(String[] args) {
        printString(new PrintB() {
            @Override
            public void print(String s) {
                MethodRerObject obj = new MethodRerObject();
                obj.printUpperCase(s);
            }
        });

        //Lambda表達式優化
        printString((s) -> {
            MethodRerObject obj = new MethodRerObject();
                obj.printUpperCase(s);
        });

        //方法引用優化:對象MethodRerObject已經存在
        //成員方法printUpperCase已經存在

        //建立MethodRerObject對象
        MethodRerObject obj = new MethodRerObject();
        printString(obj :: printUpperCase);
    }

經過類名引用靜態成員方法

@FunctionalInterface
public interface Calculate {
    int calAbs(int a);
}
public static int absMethod(int a, Calculate cal) {
        return cal.calAbs(a);
    }

    public static void main(String[] args) {
        int number = absMethod(-10, new Calculate() {
            @Override
            public int calAbs(int n) {
                return Math.abs(n);
            }
        });

        //Lambda表達式優化
        int number2 = absMethod(-10, (n) -> {
            return Math.abs(n);
        });
        
        //在Lambda基礎上優化
        //Math工具類存在,absMethod靜態方法也存在
        int number3 = absMethod(-10, Math::abs);
    }

思考:ide

這幾個主題裏說的引用,都是在Lambda表達式中,用到的成員方法,靜態成員方法。
第一個的obj.printUpperCase(s);
這個的return Math.abs(n);

經過super引用父類成員方法

函數式接口函數

@FunctionalInterface
public interface Greatable {
    void greet();
}

父類工具

public class Human {
    public void sayHello() {
        System.out.println("hello,hehe");
    }
}

子類優化

@Override
    public void sayHello() {
        System.out.println("hello,male");
    }

    public void method(Greatable g) {
        g.greet();
    }

    public void show() {
        //最繁雜方法
        method(() -> {
            Human h = new Human();
            h.sayHello();
        });
        //由於有子父類關係,存在一個關鍵字super
        //能夠直接使用super調用父類方法
        method(() -> {
            super.sayHello();
        });

        //方法引用
        //Human h = new Human();  
        //由於存在繼承關係,因此上面這個不須要了,super表明父類
        method(super::sayHello);
    }

    public static void main(String[] args) {
        new male().show();
    }

經過this引用本類成員方法

@FunctionalInterface
public interface Richable {
    void buy();
}
public void buyHouse() {
        System.out.println("北京四合院");
    }

    public void getMarry(Richable r) {
        r.buy();
    }
    public void happy() {
        getMarry(new Richable() {
            @Override
            public void buy() {
                //爲何不能用這個
                //由於這是匿名內部類寫法,this只在本匿名內部類起做用
                this.; //XXXX!!!
            }
        });
        
        getMarry(() -> {
            this.buyHouse();
        });

        getMarry(this::buyHouse);
    }

    public static void main(String[] args) {
        new Human().happy();
    }

!!!!
此例中,能夠看出Lambda表達式並非新建了一個類,因此this依舊能夠代指本類,而使用匿名內部類,this僅僅在內部類起做用,並不能調用本類中的成員方法ui

Lambda表達式傳遞的參數,對應重寫方法的參數this

類的構造器(構造方法)引用

格式:spa

類名稱::new
@FunctionalInterface
public interface PersonInterface {
    Person13 builderPerson(String name);
}
public static void printName(String name, PersonInterface p) {
        Person13 person = p.builderPerson(name);

        System.out.println(person.getName());
    }

    public static void main(String[] args) {
        printName("hehe", (String name) -> {
            return new Person13(name);
        });

        //方法引用
        //new Person(String name)構造方法已知
        //建立對象 new已知
        //使用Person引用new建立對象
        printName("hahaha", Person13::new);
    }

new Person13(name)
這就是一個有參構造方法code

數組的構造器(構造方法)引用

@FunctionalInterface
public interface ArrayBuiler {

    int[] buildArray(int length);
}
public static int[] creatArray(int length, ArrayBuiler arr) {
        return arr.buildArray(length);
    }

    public static void main(String[] args) {
        int[] arr1 = creatArray(12, (len) -> {
            return new int[len];
        });

        //方法引用
        //已知建立int[]數組
        //數組長度也已知
        int[] ints = creatArray(12, int[]::new);

    }
相關文章
相關標籤/搜索