JAVA--高級基礎開發

  • 第二章《Stream流》
  • 方法的引用
  1. 在使用Lambda的時候,實際上傳遞的是一段代碼,拿什麼參數作什麼操做,

2.1 沉於的Lambda表達式

/*app

冗餘的 Lambda 場景dom

*/ide

public class Demo12 {函數

      public static void main(String[] args) {this

        //Lambda表達式spa

        printString(s-> System.out.println(s));.net

}對象

   public static void printString(MyInter1 myInter1){繼承

      myInter1.print("Hello,World!");接口

    }
}

@FunctionalInterface

interface MyInter1{

   public void print(String str);

}

分析: 其中 printString 方法只管調用 MyInter1 接口的 print 方法,而並無論 print 方法的具體實現邏輯會將字符串輸出到什麼地方去。而 main 方法經過 Lambda 表達式指定了函數式接口MyInter1 的具體操做方案爲:拿到 String(類型能夠推導,因此可省略)數據後,在控制檯輸出它。

2.2 用方法引用改進代碼

  • 可否省去 Lambda 的語法格式?只要引用過去就好了。

public class Demo12 {

      public static void main(String[] args) {

        //Lambda表達式

       // printString(s-> System.out.println(s));

        printString(System.out::println);

}

   public static void printString(MyInter1 myInter1){

      myInter1.print("Hello,World!");

    }

}

@FunctionalInterface

interface MyInter1{

   public void print(String str);

}

請注意其中的雙冒號::寫法,這被稱爲「方法引用」,而雙冒號是一種新的語法

2.3 方法的引用

  1. 雙冒號爲引用運算符::而它所在的表達式稱爲方法的引用,若是Lambda表達的函數方案已經存在與某個方法的實現中,那麼能夠經過雙冒號來引用該方法做爲Lambda表達式的替代者。
  2. 例如,System.out 對象中有一個重載的 println(String)方法剛好就是咱們所須要的,那麼對於printString 方法的函數式接口參數,對比如下兩種寫法,徹底等效:
  • Lambda 表達式寫法:s->System.out.println(s);
  • 方法引用寫法:System.out::println
  1. 第一種語義指的是:拿到參數後經Lambda表達式,在傳遞給System.out.println方法。
  2. 第二種語義指的是:  直接讓System.out中的println方法來代替Lambda表達式。
  3. 兩種寫法的執行效果徹底同樣,而第二種方法引用的寫法複用了已有方案,更加簡潔。
  4. 【注意:Lambda 中傳遞的參數必定是方法引用中的那個方法能夠接收的類型,不然會拋出異常】
  • 推導與省略

若是使用 Lambda,那麼根據「可推導就是省略」的原則,無需指定參數類型,也無需指定重載形式---它們都被自動推導,而若是使用方法引用,也一樣能夠根據上下文進行推導。

  • 函數式接口是 Lambda 的基礎,而方法引用是 Lambda 的孿生兄弟。

2.4經過對象名引用成員方法

//對象名 引用成員方法的引用

public class Test7 {

    public static void main(String[] args) {

        String str="LIWENJIE";

        //skips(()->str.toLowerCase());

        //轉換爲小寫

        skips(str::toLowerCase);

    }

    public static  void skips(Supplier<String>supplier){

        String  ss=supplier.get();

        System.out.println(ss);

    }

}

 

2.5經過類名引用靜態方法

 

//經過類名靜態方法的引用

public class Test8 {

    public static void main(String[] args) {

         display(Math::random);

         display(()->Math.random());

    }

    public static  void display(Supplier<Double>set) {

       double  aa=set.get();

        System.out.println(aa);

    }

}

 

2.6經過Super關鍵字引用成員方法

若是存在繼承關係,當 Lambda 中須要出現 super 調用時,也可使用方法引用進行替代。

首先定義一個函數式接口

//Super引用成員方法

public class Test9 {

    public static void main(String[] args) {

        //建立當前類的對象

        F1  ff=new F1();

        ff.apple();

    }

 

}

interface  inface1{

    void  meth();

}

//建立父類

class  F1{

    public  void  apple(){

        System.out.println("李文傑");

    }

}

//建立子類

class S1  extends  F1{

    @Override

    public void apple() {

        System.out.println("天水市");

    }

    //定義方法

    public  void apple1(inface1 inface11){

        inface11.meth();

    }

    //引用當前類父類的方法

    public  void apple2(){

      //引用當前類父類的方法

       apple1(super::apple);

        //引用當前類的方法

       apple1(this::apple);

    }

 

}

2.7經過 this 引用成員方法

//this引用成員方法

public class Test10 {

    public static void main(String[] args) {

        Myshe  ss=new Myshe();

        ss.method();

    }

}

interface  my{

    void  test();

}

class Myshe{

    public void meth(my  ss){

        ss.test();

    }

    public void  skip(){

        System.out.println("我是成員方法");

    }

    //引用成員方法

public  void method(){

  //Lambda表達式的寫法

meth(()->this.skip());

//方法的引用

        meth(this::skip);

    }

}

相關文章
相關標籤/搜索