no-image

Java 8學習之Lambda表示式

                                    

做APP,小程式就上開源眾包。世界盃期間免費領2600元啟動金。
>>>
  

一、lambda表示式

一個lambda表示式包含三個部分:

一段程式碼
引數
自由變數的值,這裡的自由指的是哪些不是引數並且沒有在程式碼中定義的變數。

示例:

public static void repeat(String text, int count) {
    Runnable r = () -> {
        for (int i = 0; i < count; i  ) {
            System.out.println(text);
            Thread.yield();
        }
    };

    new Thread(r).start();
}

含有自由變數的程式碼塊被稱為“閉包”。

內部類也會補貨閉合作用域中的值。在Java 8之前,內部類只允許訪問final的區域性變數。為了適應lambda表示式,這條規則也被放寬了。一個內部類可以訪問任何有效的final區域性變數–即任何值不會發生變化的變數。

二、預設方法

public interface DefaultDemo {
    long getId();

    default String getName(){
        return "name";
    };
}

預設方法終結了以前的一種經典模式,即提供一個介面,以及一個實現介面的大多數或全部方法的抽象類,例如Collection/AbstractCollection。現在你只需要在介面中實現那些方法。

如果一個介面中定義了一個預設方法,而另一個父類或者介面中又定義了一個同名的方法,該選擇哪個呢?Java中的規則要簡單得多,如下:

選擇父類中的方法。如果一個父類提供了具體的實現方法,那麼介面中具有相同名稱和引數的預設方法會被忽略。
介面衝突。如果一個父介面提供了一個預設方法,而另一個介面也提供了一個具有相同名稱和引數型別的方法(不管是不是預設方法),那麼你必須通過覆蓋該方法來解決衝突。

三、方法引用

表示式System.out::println是一個方法引用,等同於lambda表示式x -> System.out.println(x)。

::操作符將方法名和物件或類的名字分隔開來。以下是三種主要的使用情況:

物件::例項方法
類::靜態方法
類::例項方法

例如:Math::pow等同於(x,y)->Math.pow(x,y),String::compareToIgnoreCase等同於(x,y)->x.compareToIgnoreCase(y)。

注意:如果有多個同名的過載方法,編譯器會試圖從上下文中找到最匹配的一個方法。例如,有兩個版本的Math.max方法,一個接收整型作為引數,而另一個接收double型別的值。究竟會選擇哪一個方法取決於Math:max被轉換為的函式式介面的方法引數。同lambda表示式類似,方法引用也不會獨立存在,他們經常被用於轉換為函式式介面的例項。


(adsbygoogle = window.adsbygoogle || []).push({});

function googleAdJSAtOnload() {
var element = document.createElement(“script”);
element.src = “//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js”;
element.async = true;
document.body.appendChild(element);
}
if (window.addEventListener) {
window.addEventListener(“load”, googleAdJSAtOnload, false);
} else if (window.attachEvent) {
window.attachEvent(“onload”, googleAdJSAtOnload);
} else {
window.onload = googleAdJSAtOnload;
}