Lambda Expressions
可以把Lambda表达式理解为简洁地表示可传递的匿名函数的一种方式
1. Lambda的特点:
- 匿名:它不像普通方法一样有名字。
- 函数:它除了不像方法一样属于某一个类外,其他的特性和方法是一样的。
- 传递:Lambda表达式可以作为参数传递给方法或存储在变量中。
- 简洁:不需要像匿名类一样写很多模板代码。
2. 为什么用Lambda?
因为用了Lambda明显代码更加清晰,简洁了
用之前:
inventory.sort(new Comparator<Apple>() {
public int compare(Apple a1, Apple a2){
return a1.getWeight().compareTo(a2.getWeight());
}});
用之后:
inventory.sort((a1, a2) -> a1.getWeight().compareTo(a2.getWeight()));
3. Lambda的结构
- 参数列表 - 这里它采用了Comparator中compare方法的参数,两个Apple。
- 箭头 -> - 把参数列表与Lambda主体分隔开。
- Lambda主体 - 比较两个Apple的重量。表达式的返回值就是Lambda的返回值。
4. Lambda的主要形式
(parameters) -> expression
或者:
(parameters) -> { statements; }
函数式接口
只定义一个抽象方法的接口
1. 例子
@FunctionalInterface
public interface Runnable {
public void run();
}
Runnable r = () -> System.out.println("Hello World!");
2. Java自带的库中一些比较有用的函数式接口
Predicate<T>
- a boolean-valued property of an objectConsumer<T>
- an action to be performed on an objectFunction<T,R>
- a function transforming aT
to aR
Supplier<T>
- provide an instance of aT
(such as a factory)UnaryOperator<T>
- a function fromT
toT
BinaryOperator<T>
- a function from(T,T)
toT
3. 函数式接口和Lambda有什么联系?
Lambda表达式允许你直接以内联的形式为函数接口的抽象方法提供实现,并把整个表达式作为函数式接口的实例。
讲人话:
当你调用的函数参数是函数式接口的时候,你可以先用Lambda来实例化一个这个接口,并作为值传入。
4. 再看一遍刚刚的例子
使用Lambda之前:
inventory.sort(new Comparator<Apple>() {
public int compare(Apple a1, Apple a2){
return a1.getWeight().compareTo(a2.getWeight());
}});
使用Lambda之后:
inventory.sort((a1, a2) -> a1.getWeight().compareTo(a2.getWeight()));
方法引用
把已经存在的方法当成一个函数接口的实例
1.例子
class Person {
private String name;
private int age;
public int getAge() {return this.age;}
public String getName() {return this.name;}
}
Person[] people = ...;
Comparator<Person> byName = Comparator.comparing(Person::getName);
Arrays.sort(people, byName);
2. 方法引用的类型
- 静态方法引用 (
ClassName::staticMethod
) - 一个实例对象的方法引用 (
instanceRef::instanceMethod
) - 只想任意类型实例方法的方法引用 (
ClassName::instanceMethod
) - 一个对象的父类方法引用 (
super::instanceMethod
) - 类的构造方法引用 (
ClassName::new
) - 数组的构造方法引用 (
TypeName[]::new
)
3. 方法引用对应的lambda
- 静态方法引用 (
ClassName::staticMethod
)ClassName::staticMethod (args) -> ClassName.staticMethod(args)
- 一个实例对象的方法引用 (
instanceRef::instanceMethod
)expr::instanceMethod (args) -> expr.instanceMethod(args)
- 指向任意类型实例方法的方法引用 (
ClassName::instanceMethod
)ClassName::instanceMethod (arg0, rest) -> arg0.instanceMethod(rest) 换一种思考,其实是ClassName::instanceMethod(arg0, rest) 当然这种调用方法在Java里面是没有的
- 一个父类对象的方法引用 (
super::instanceMethod
)super::instanceMethod (args) -> super.instanceMethod(args)
- 类的构造方法引用 (
ClassName::new
)ClassName::new (args) -> new ClassName(args)
- 数组的构造方法引用 (
TypeName[]::new
)TypeName[]::new () -> new TypeName[]
总结
Stream的内容比较多,下次再讲。
to be continue…