Functional Interfaces
每個lambda表達式對應一個類型,通過接口來指定。一個叫做functional interface必須只包含一個抽象方法的聲明。每個lambda表達式會匹配到抽象方法。因爲default方法不是抽象的,當然可以在functional interface中隨意添加。
public class functionalInterface {
// @FunctionalInterface
// 即使@FunctionalInterface被忽略了,代碼依然是有效的
interface Converter<F, T> {
T convert(F from);
// T cccc(F ssss); 不可以有第二個抽象方法,否則編譯器會認爲這不是FunctionalInterface
}
public static void main(String[] args){
Converter<String, Integer> converter = (from) -> Integer.valueOf(from);//Lambda表達式
Integer converted = converter.convert("123");
System.out.println(converted); // 123
}
}
Method and Constructor References
利用關鍵字::簡化靜態方法引用
Converter<String, Integer> converter = Integer::valueOf;//關鍵字::
Integer converted = converter.convert("123");
System.out.println(converted1); // 123
引用對象方法
class Something {
String startsWith(String s) {
return String.valueOf(s.charAt(0));
}
}
Something something = new Something();
Converter<String, String> converter2 = something::startsWith;
String converted2 = converter2.convert("Java");
System.out.println(converted2); // "J"
調用構造器
interface PersonFactory<P extends Person> {
P create(String firstName, String lastName);
}
class Person {
String firstName;
String lastName;
Person() {}
Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
PersonFactory<Person> personFactory = Person::new;
Person person = personFactory.create("Peter", "Parker");
通過Person::new
我們創建了一個Person構造器。Java編譯器通過匹配PersonFactory.create
的簽名來選擇正確的構造器。
Lambda Scopes
從Lambda表達式中獲取外部變量和匿名對象很相似。可以從本地outer scope中獲取final變量和實例域和靜態變量。
Accessing local variables
從Lambda表達式的outer scope中獲取final局部變量。
interface Converter<F, T> {
T convert(F from);
}
final int num = 1;
Converter<Integer, String> stringConverter =(from) -> String.valueOf(from + num);
System.out.println(stringConverter.convert(2)); // 3
num
不必聲明爲final,代碼仍然是有效的
int num = 1;
Converter<Integer, String> stringConverter =
(from) -> String.valueOf(from + num);
stringConverter.convert(2); // 3
但是,在編譯時num
隱含着是final的,如下的代碼就未能編譯成功
int num = 1;
Converter<Integer, String> stringConverter =
(from) -> String.valueOf(from + num);
num = 3;
報錯信息:
Local variable num defined in an enclosing scope must be final or effectively
Accessing fields and static variables
和局部變量表不同,我們可以在lambda表達式中讀寫實力域和靜態變量表
class Lambda4 {
static int outerStaticNum;
int outerNum;
void testScopes() {
Converter<Integer, String> stringConverter1 = (from) -> {
outerNum = 23;
return String.valueOf(from);
};
Converter<Integer, String> stringConverter2 = (from) -> {
outerStaticNum = 72;
return String.valueOf(from);
};
}
}