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
數組
注意: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);
函數式接口函數
@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(); }
@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); }