【JDK 8特性】Lambda 入門

樂猿社區,程序員的花果山javascript

Lambda 管中窺豹

什麼是 Lambda 表達式?簡單的來講,Lambda 表達式是一個匿名函數,Lambda 表達式基於數學中的λ演算得名,直接對應其中的 Lambda 抽象( lambda abstraction ),是一個匿名函數,既沒有函數名的函數。Lambda 表達式能夠表示閉包(注意和數學傳統意義的不一樣)。你也能夠理解爲,簡潔的表示可傳遞的匿名函數的一種方式:它沒有名稱,但它有參數列表、函數主體、返回類型,可能還有一個能夠拋出異常的列表。java

有時候,咱們爲了簡化代碼而去使用匿名類,雖然匿名類能簡化一部分代碼,可是看起來很囉嗦。爲了更好的的提升開發的效率以及代碼的簡潔性和可讀性,Java8 推出了一個核心的新特性之一:Lambda 表達式。程序員

Java8 以前,使用匿名類給用戶排序的代碼:express

users.sort(new Comparator<User>() {
    @Override
    public int compare(User o1, User o2) {
        return o1.getAge().compareTo(o2.getAge());
    }
});

而有了lambda後,代碼可能會是這樣的編程

Comparator<User> byWeight = (User a1, User a2) -> a1.getAge().compareTo(a2.getAge());

還多是這樣的閉包

Comparator<User> byAge = Comparator.comparing(User::getAge);

看上去更簡潔了,少了好多行代碼是否是?jvm

Lambda的本質

lambda的本質就是匿名函數編程語言

咱們都知道在java裏賦值語句是這樣的ide

String str = "123";

可是若是你想把「一塊代碼塊」賦值給一個變量,該怎麼作呢?,好比在javascript中能夠這麼寫函數

var fun = ()->{alert(1)}

java作爲老大哥,能不能有相似的寫法呢?

codeSpan = public void doSomething(){System.out.pringln("樂猿社區")};

在java8以前是作不到,但有了java8以後,咱們能夠一步步簡化上面的代碼實現相似的效果

函數式接口

這樣,咱們就成功的很是優雅的把「一塊代碼」賦給了一個變量。而「這塊代碼」,或者說「這個被賦給一個變量的函數」,就是一個Lambda表達式。看到可能會有javaer要問,codeSpan的類型是什麼呢?

在Java 8裏面,全部的Lambda的類型都是一個接口,而Lambda表達式自己,也就是」一塊代碼「,須要是這個接口的實現。簡而言之就是,Lambda表達式自己就是一個接口的實現。俗話說一圖勝千言:

這種只有一個接口函數須要被實現的接口類型,咱們叫它」函數式接口「。爲了不後來的人在這個接口中增長接口函數致使其有多個接口函數須要被實現,變成"非函數接口」,咱們能夠在這個上面加上一個聲明@FunctionalInterface, 這樣別人就沒法在裏面添加新的接口函數了:

@FunctionalInterface
public interface MyLambdaInterface {
    void doSomething();
}

這樣一個完整的函數式接口實現以下

public class Test {
    MyLambdaInterface codeSpan = () -> System.out.println(""樂猿社區);
}

而在Java7以前實現接口以下

public class MyInterfaceImpl implements MyLambdaInterface{
    @Override
    public void doSomething() {
        System.out.println("樂猿社區");
    }
}

在jvm層,這兩種寫法的本質同樣的,但明顯java8的寫法更簡潔清晰。

jdk默認的函數式接口

接口 參數 返回值 類別
Consumer T void 消費型接口
Supplier None T 供給型接口
Function T R 函數型接口
Predicate T boolean 斷言型接口

基礎語法

在lambda中咱們遵循以下的表達式來編寫

expression = (variable) -> action
  • variable: 這是一個變量,一個佔位符。像x,y,z,能夠是多個變量;
  • action: 這裏我稱它爲action, 這是咱們實現的代碼邏輯部分,它能夠是一行代碼也能夠是一個代碼片斷

能夠看到Java中lambda表達式的格式:參數、箭頭、以及動做實現,當一個動做實現沒法用一行代碼完成,能夠編寫 一段代碼用{}包裹起來。

lambda表達式能夠包含多個參數,例如:

int sum = (x, y) -> x + y;

這時候咱們應該思考這段代碼不是以前的x和y數字相加,而是建立了一個函數,用來計算兩個操做數的和。 後面用int類型進行接收,在lambda中爲咱們省略去了return。

Lambda做用

  • lambda最直觀的做用就是使得代碼變得異常簡潔
  • Lambda容許把函數做爲一個方法的參數(函數做爲參數傳遞進方法中)

寫在最後的

lambda靈活多變,內容博大精深,本文只是介紹了lambda的基本原理以及基礎語法,順帶講述了下什麼是函數式接口,讓初次接觸java8的Javaer對lambda有了一個大概的瞭解。

鼓勵把新的Java8特性引入到目前的項目中,一個長期配合的團隊以及一門古老的編程語言都須要不斷的注入新活力,不然不進則退

相關文章
相關標籤/搜索