標籤:bool man methods 設計 tle com 基本文法 one ret
Lamda運算式可以理解為簡潔地表示可傳遞的匿名函數的一種方式:它沒有名稱,但它有參數列表/函數主體/傳回型別,可能還有一個可以拋出的異常列表。
Lamda運算式由參數/箭頭和主體組成:
(Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());
之前的代碼形式:
Comparator<Apple> byWeight = new Comparator<Apple>() {
public int compare(Apple a1, Apple a2) {
return a1.getWeight().compareTo(a2.getWeight());
}
}
Java 8 中有效Lamda運算式:
1, (String s) -> s.length()
具有一個String類型的參數,並返回一個int。Lamda運算式沒有return語句,因為已經隱含了return。
2, (Apple a) -> a.getWeight() > 150
參數為Apple類型,返回一個boolean類型。
3, (int x, int y) -> {
System.out.println("Result");
System.out.println(x+y);
}
該Lamda運算式具有兩個int類型的參數而沒有傳回值。Lamda運算式可以包含多行語句。
() -> {return "Mario";}
該Lamda運算式也是有效。
4, () - > 42
該Lamda運算式沒有參數,返回一個int
5, (Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight())
該運算式具有兩個Apple類型的參數,返回一個int
無效Lamda運算式:
(Integer i) -> return "Alan" + i;
(String s) -> {"IronMan";}
第一個運算式中,return是一個控制流程語句。要使得這個語句有效,需要加上花括弧。
第二個運算式中,"IronMan" 是一個運算式,不是語句。要使得此Lamda有效,可以去除花括弧和分號。
Lamda基本文法:
(parameters) -> expression
or
(parameters) -> { statements;}
可以使用Lamda運算式的地方 —— 函數式介面
函數式介面就是只定義一個抽象方法的介面。如Comparator和Runnable介面。
Lamda運算式可以直接以內聯的形式為函數式介面的抽象方法提供實現,並把整個運算式作為函數式介面的執行個體。
函數式介面的抽象方法的簽名就是Lamda運算式的簽名。這種抽象方法叫做函數描述符。
新的Java API中,函數式介面帶有@FunctionalInterface的標註。如果用@FunctionalInterface定義了一個介面,但它卻不是函數式介面的話,便一起將返回一個提示原因的錯誤,例如“Multiple non-overriding abstract methods found in interface Foo”,表明存在多個抽象方法。
使用Lamda運算式的步驟:
1,行為參數化:
提取Lamda運算式,設計好參數,函數主體和傳回值。
2,使用函數式介面來傳遞行為:
建立一個能匹配Lamda運算式的函數式介面I,並把這個介面作為參數傳遞給需要使用Lamda運算式的函數M。
3,執行函數式介面中的行為
在函數M中調用介面I中的抽象函數
4,傳遞Lamda運算式
常用函數式介面:
Java 8 以前已有的函數式介面:
Comparable
Runnable
Callable
Java 8 在java.util.function包中引入的新的函數式介面:
Predicate
@FunctionalInterfacepublic interface Predicate<T>{ boolean test(T t);}public static <T> List<T> filter(List<T> list, Predicate<T> p) { List<T> results = new ArrayList<>(); for(T s: list){ if(p.test(s)){ results.add(s); } } return results;}Predicate<String> nonEmptyStringPredicate = (String s) -> !s.isEmpty();List<String> nonEmpty = filter(listOfStrings, nonEmptyStringPredicate);
Consumer
@FunctionalInterfacepublic interface Consumer<T>{ void accept(T t);}public static <T> void forEach(List<T> list, Consumer<T> c){ for(T i: list){ c.accept(i); }}forEach(Arrays.asList(1,2,3,4,5),(Integer i) -> System.out.println(i));
Function
@FunctionalInterfacepublic interface Function<T, R>{ R apply(T t);}public static <T, R> List<R> map(List<T> list,Function<T, R> f) { List<R> result = new ArrayList<>(); for(T s: list){ result.add(f.apply(s)); } return result;}List<Integer> l = map(Arrays.asList("lambdas","in","action"),(String s) -> s.length());
Lamda及函數式介面例子
| 使用案例 |
Lambda的例子 |
對應的函數式介面 |
| 布林運算式 |
(List<String> list) -> list.isEmpty() |
Predicate<List<String>> |
| 建立對象 |
() -> new Apple(10) |
Supplier<Apple> |
| 消費一個對象 |
(Apple a) -> System.out.println(a.getWeight())
|
|
| |
|
|
| |
|
|
| |
|
|
Lambda的例子 對應的函數式介面
消費一個對象 (Apple a) ->
System.out.println(a.getWeight())
Consumer<Apple>
從一個對象中
選擇/提取
(String s) -> s.length() Function<String, Integer>或
ToIntFunction<String>
合并兩個值 (int a, int b) -> a * b IntBinaryOperator
比較兩個對象 (Apple a1, Apple a2) ->
a1.getWeight().compareTo(a2.getWeight())
Comparator<Apple>或
BiFunction<Apple, Apple, Integer>
或ToIntBiFunction<Apple, Apple>
《Java 8 實戰》(二)—— Lamda