Lambda表达式的由来
Lambda表达式,产于JDK8,使得Java能够支持简单的函数式编程。主要原因还是面向对象编程太过完整,结构操作不明确,代码太过冗余。Lambda表达式是Java迎合时代的产物。
代码说明
计算两个整型的和的方法,完全按照Java中对象至上的观念,先定义一个接口,接口中提供抽象方法,然后再定义接口实现类。
定义接口
interface Add{
int add(int a,int b);
}
定义接口实现类:
// 普通内部类
class AddImpl implements Add{
@Override
public int add(int a, int b) {
return a + b;
}
}
当然我们也可以使用匿名内部类来简化代码。
public class TestLambda {
public static void main(String[] args) {
//匿名内部类
Add sum = new Add(){
@Override
public int add(int a,int b){
return a + b;
}
};
}
}
Lambda表达式优化代码
Add sum2 = (a,b) -> a + b;
测试代码
public class TestLambda {
public static void main(String[] args) {
//匿名内部类
Add sum = new Add(){
@Override
public int add(int a,int b){
return a + b;
}
};
Add sum2 = (a,b) -> a + b;
System.out.println("普通内部类" + new AddImpl().add(10,20));
System.out.println("匿名内部类:" + sum.add(10,20));
System.out.println("Lanbda表达式:" + sum2.add(10,20));
}
}
输出结果:
第一次看到这样的代码,并没有被惊艳到,反而看着很懵,这代码写的连箭头都用上了.,看着脑壳痛。但自己不会用不代表大佬不会用,为了看懂大佬写得代码,自己也必须好好学习一番。而且设计者这样设计肯定有他的道理。
Lambda表达式的基本语法
(参数) -> {方法体};
其实这个类比接口中的方法也就不难理解了。
- ()就是接口中抽象方法的括号。接口方法如果有参数,也必须写参数,但参数的类型可以忽略,该数据类型由编译器推断得出,称为“类型推断” ,其中当仅有一个参数时,小括号可以省略。
- ->:寓意实现(称为箭头或者Lambda操作符)
- {} 要实现的抽象方法的方法体。其中当方法体仅有一条语句时,可以省略大括号,且是return语句时,return 也可以省略。
Lambda表达式本质其实和匿名内部类一样,该表达式的结果会产生一个匿名的接口实现类对象。
Lambda表达式的用法示例
- 无参数,无返回值的写法
interface A{
void fun();
}
A a = () -> System.out.println("hehe");
- 仅有一个参数无返回值的写法
interface B{
void fun(int c);
}
// 一个参数时括号可省略
B b = num -> System.out.println("hehe");
- 有多个参数有返回值的写法
interface C{
int fun(int a,int b);
}
C c = (num1,num2) -> {return num1 + num2;};
// 单条语句时 return 和 {} 皆可省略
C c = (num1,num2) -> num1 + num2;
- 方法体有多条语句的写法
interface D{
int sum(int n);
}
D d = (n) -> {
int sum = 0;
for(int i = 0; i <= n; i++){
sum += i;
}
return sum;
}; // 分号很重要
Functional接口
要想使用函数式编程或者说使用Lambda表达式的前提是接口只能有一个抽象方法。(可以有多个default修饰的默认方法,和static修饰的静态方法)为了显示说明该接口可以用于函数式编程提供了一个@FunctionalInterface
注解。
为了使用方便,不再需要我们自己创建接口,JDK8内置了四个核心函数型接口:
- 消费性接口(有参无返回值)
Consumer<T> void accept(T t);
- 供给型接口(无参有返回值)
public interface Supplier T get();
- 功能型函数式接口(有参有返回值)
public interface Function<T, R> R apply(T t);
- 断言型接口(有参返回值为boolean类型)
public interface Predicate boolean test(T t);
Lambda表达式练习对自定义类型排序
自定义Person类
class Person{
String name;
Integer age;
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
利用比较器排序(传一个Lambda表达式)
public static void main(String[] args) {
Person[] arr = new Person[3];
arr[0] = new Person("Jack",18);
arr[1] = new Person("Tom",20);
arr[2] = new Person("Lucy",19);
Arrays.sort(arr,(Person p1,Person p2) -> p1.age - p2.age);
for(Person per : arr){
System.out.println(per);
}
}
输出结果;