一文掌握Lambda表達式

Java8 lambda表達式

lambda表達式初識

​ lambda表達式的重要用法就是簡化某些匿名類的寫法,實際上lambda不僅僅是匿名內部類的語法糖,JVM內部也是通過invokedynamic指令來實現lambda表達式的。

​ 也正是因爲如此匿名類在編譯以後會創建一個新的匿名內部類出來,而由於Lambda是調用JVMinvokedynamic指令實現的,所以並不會產生新類。

​ 其實lambda表達式描述了一個代碼塊(匿名方法);可以將其作爲參數傳遞給構造方法或者普通方法以便後續執行,如下:

()->System.out.println("冢狐")
  • 其中()爲lambda表達的參數列表(可以有也可以沒有)
  • ->標識這段代碼爲lambda表達式,後面就是要執行的代碼。

其中lambda最常見的用途就是新建線程,有時候爲了省事會用下面的方法創建並啓動一個線程

public static void main(String[] args) {
    new Thread(() -> System.out.println("冢狐")).start();
}

Lambda語法

lambda標準的語法如下:

(parameter-list)->{express-or-statements}
  • 其中()中的parameter-list是以逗號分隔的參數,在其中可以指定參數類型,也可以不執行(編譯器會根據上下文進行推斷)

  • ->作爲lambda的標識符,主要作用就是告訴這是一個lambda表達式

  • {}中爲lambda的主體,主要通過其中的代碼進行要做的事情

    • 爲變量賦值

      Runnable r = (){System.out.print("冢狐")};
      
    • 作爲return的結果:

      static FileFilter getFilter(String ex){
          return (pathname)->pathname.toString().endWith(ex);
      }
      
    • 作爲數組元素:

      final PathMatcher matchers[] =
      {
              (path) -> path.toString().endsWith("zhong"),
              (path) -> path.toString().endsWith("hu")
      };
      
    • 作爲普通方法或者構造方法的參數

      new Thread(() -> System.out.println("冢狐")).start();
      

使用Lambda表達式的要求

​ 能夠使用lambda的依據就是必須有相應的函數接口。

​ 函數接口是指內部只有一個抽象方法的接口,這一點和java是強類型語言吻合,即不能在代碼的任何地方使用lambda表達式。

​ lambda的類型就是對於函數接口的類型。

自定義函數接口

自定義函數接口還是比較容易的,只需要編寫一個只有一個抽象方法的接口即可

// 自定義函數接口
   public static void main(String[] args) {
       ConsumerInterFace<String> consumer = str-> System.out.println(str);
       consumer.accept("自定義函數接口");
    }

    @FunctionalInterface
    public interface ConsumerInterFace<T>{
        void accept(T t);
    }

java內置四大核心函數式接口

函數式接口 參數列表 返回類型 用途
Consumer<T>消費型接口 T void 對類型爲T的對象應用操作,包含方法void accept(T t);
Supplier<T>供給型接口 T 返回類型爲T的對象,包含方法T get();
Function<T,R>函數型接口 T R 對類型爲T的對象應用操作,並返回結果類型爲R的對象,包含方法R apple(T t);
Predicate<T>斷定型接口 T boolean 確定類型爲T的對象是否滿足某約束,並返回boolean值,包含方法boolean test(T t);

Lambda和this關鍵字

​ 由於lambda表達式並不會引入新的作用域,即lambda表達式的主體內使用的this關鍵字和其所在的類實例相同。

示例:

public class Player {

    public static void main(String[] args) {
        new Player().work();
    }

    public void work() {
        System.out.printf("this = %s%n", this);

        Runnable r = new Runnable() {
            @Override
            public void run() {
                System.out.printf("this = %s%n", this);
            }
        };
        new Thread(r).start();
        new Thread(() -> System.out.printf("this = %s%n", this)).start();
    }
}

work()中的代碼可以分爲三個部分:

  • 單獨的this關鍵字
    • 這裏的this爲main()方法中通過new關鍵字創建的Player對象
  • 匿名內部類中的this關鍵字
    • 這裏的this爲work()方法中通過new關鍵字創建的Runnable對象
  • Lambda表達式中的this關鍵字
    • 這個和第一個單獨的this是一個

輸出結果:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Nuq1rUxN-1592796226199)(https://raw.githubusercontent.com/iszhonghu/Picture-bed/master/img/20200622101950.png)]

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