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);
};
}
}