原文地址 en cn
下載 DemoJava? 8 包含一些重要的新的語言功能,為您提供了構建程序的更簡單方式。Lambda 表達式 為內聯代碼塊定義一種新語法,其靈活性與匿名內部類一樣,但樣板文件要少得多。接口更改使得接口可以添加到現有接口中,同時又不會破壞與現有代碼的兼容性。本文將了解這些更改是如何協同工作的。
Java 8 的最大變化在于添加了對 lambda 表達式 的支持。Lambda 表達式是可按引用傳遞的代碼塊。類似于一些其他編程語言中的閉包:它們是實現某項功能的代碼,可接受一個或多個輸入參數,而且可返回一個結果值。閉包是在一個上下文中定義的,可訪問(對于 lambda 表達式而言是只讀訪問)來自上下文的值。
如果您不熟悉閉包,不用害怕。Java 8 lambda 表達式其實是匿名內部類的一種特殊化,而幾乎所有 Java 開發人員都熟悉匿名內部類。匿名內部類提供了一個接口的內聯實現,或者一個基類的子類,我們一般只會在代碼中的一個地方使用它。Lambda 表達式的使用方式一樣,但它有一個簡寫的語法,使得它們比標準內部類定義更簡潔。
在本文中,您將了解如何在各種情形下使用 lambda 表達式,還將了解 Java 語言 interface 定義的相關擴展。
了解 lambdasJava 終于有 Lambda 表達式了~
.NET 關于 Lambda 表達式以及函數委托等的實現,從 2008 年開始,經歷了一個技術的演化過程,參看“沒有 Lambda 演算何來匿名函數——匿名函數(匿名方法和Lambda)、委托、LINQ”和“.NET C# 聲明、實例化和使用委托以及委托在 C# 中的發展”~
Lambda 表達式始終是 Java 8 稱為函數式接口 的一個對象的實現:定義單一抽象方法的 interface 類。對單一抽象方法的限制很重要,因為 lambda 表達式語法不使用方法名。相反,該表達式使用了 duck typing(匹配參數和返回類型,就像在許多動態語言中所做的那樣)來確保所提供的 lambda 與預期的接口方法相兼容。
duck typing,鴨子類型,James Whitcomb Riley 提出的一個著名論斷,“當看到一只鳥走起來像鴨子、游泳起來像鴨子、叫起來也像鴨子,那么這只鳥就可以被稱為鴨子。”我們并不關心對象是什么類型,到底是不是鴨子,只關心行為。
在清單 1 的示例中,使用了 lambda 來對 Name 實例進行排序。main() 方法中的第一個代碼塊使用了一個匿名內部類來實現 Comparator<Name> 接口,第二個代碼塊使用了 lambda 表達式。
清單 1. 匿名內部類與 Lambda 表達式的對比
public class Name { public final String firstName;
public final String lastName;
public Name(String first, String last) { firstName = first;
lastName = last;
}
// only needed for chained comparator
public String getFirstName() { return firstName;
}
// only needed for chained comparator
public String getLastName() { return lastName;
}
// only needed for direct comparator (not for chained comparator)
public int compareTo(Name other) { int diff = lastName.compareTo(other.lastName);
if (diff == 0) { diff = firstName.compareTo(other.firstName);
}
return diff;
}
...
}
public class NameSort { PRivate static final Name[] NAMES = new Name[] {
new Name("Sally", "Smith"), ...
};
private static void printNames(String caption, Name[] names) { ...
}
public static void main(String[] args) { // sort array using anonymous inner class
Name[] copy = Arrays.copyOf(NAMES, NAMES.length);
Arrays.sort(copy, new Comparator<Name>() { @Override
public int compare(Name a, Name b) { return a.compareTo(b);
}
});
printNames("Names sorted with anonymous inner class:", copy); // sort array using lambda expression
copy = Arrays.copyOf(NAMES, NAMES.length);
Arrays.sort(copy, (a, b) -> a.compareTo(b));
printNames("Names sorted with lambda expression:", copy); ...
}
}
在 清單 1 中,lambda 用于替代一個慣用匿名內部類。這種慣用內部類在實踐中都很常見,因此 lambda 表達式立即贏得了 Java 8 程序員的器重。(在本例中,內部類和 lambda 都使用在 Name 類中實現的一個方法來執行比較工作。如果 compareTo() 方法代碼內聯在 lambda 中,那么表達式就不怎么簡潔了。)
新的 java.util.function 包定義旨在使用 lambdas 的廣泛函數式接口。這些接口分為幾大類:
void) 這些類別中大部分都包含幾個用于處理基本原始參數或返回類型的變量。許多接口定義可用于組合實例的方法,如清單 2 中所示。
清單 2. 組合謂詞
// 使用謂詞組合刪除匹配的名稱
List<Name> list = new ArrayList<>();
for (Name name : NAMES) { list.add(name);
}
Predicate<Name> pred1 = name -> "Sally".equals(name.firstName);
Predicate<Name> pred2 = name -> "Queue".equals(name.lastName);
list.removeIf(pred1.or(pred2));
printNames("Names filtered by predicate:", list.toArray(new Name[list.size()]));清單 2 中的代碼定義了一對 Predicate<Name>,一個與名 Sally 匹配,第二個與姓 Queue 匹配。pred1.or(pred2) 方法調用構建所定義的組合謂詞,方法是依次應用
|
新聞熱點
疑難解答