Java 8 新特性之 lambda 表达式以及 函数式编程
lambda
表达式是Java 8
的一个很重要的新特性,对于我们Java
开发者来说,学会使用lambda
是十分重要滴。
本文带你快速学会并掌握lambda
表达式的使用以及函数式编程~~~
Quick Start
lambda
表达式能用在两个地方:
- 创建匿名内部类
- 创建对象
我们直接上代码
创建匿名内部类
public static void main(String[] args) {
// 使用 lambda 表达式创建匿名内部类
Thread thread = new Thread(() -> {
System.out.println("Run!");
});
// 以下为优化
// 由于只有一行代码,可以对 lambda 表达式进行优化
Thread thread = new Thread(() -> System.out.println("Run!");
}
创建对象
public static void main(String[] args) {
// 这里我直接使用了 Integer 对象,大家完全可以换成自己创建的对象
Comparator<Integer> comparator = (Integer n1, Integer n2) -> {return n1 - n2;};
// Apple 这个实体有 name(String)、weight(int) 这个两个属性
Comparator<Apple> comparatorApple = (Apple a1, Apple a2) -> {return a1.getWeight() - a2.getWeight();};
// 实际上,可以利用类型推导进行优化
Comparator<Integer> comparator = (n1, n2) -> {return n1 - n2;};
Comparator<Apple> comparatorApple = (a1, a2) -> {return a1.getWeight() - a2.getWeight();};
// 更进一步,由于只有一行
Comparator<Integer> comparator = (n1, n2) -> n1 - n2;
Comparator<Apple> comparatorApple = (a1, a2) -> a1.getWeight() - a2.getWeight();
// 由于 Integer 本身自带比较方法,我们可以使用方法引用再次优化
Comparator<Integer> comparator = Integer::compareTo;
}
怎么样,lambda
表达式漂亮吧!
相信大家也看到了我对代码的优化,这些就涉及到了lambda
表达式更进一步的学习,引用
引用
方法引用
我们能使用的有方法引用以及构造函数引用,上面的代码已经演示过方法引用,这是个什么东西呢,
Comparator<Integer> comparator = Integer::compareTo;
给大家看看如果不使用方法引用的代码是怎么样的,
Comparator<Integer> comparator = (n1, n2) -> n1.compareTo(n2);
可以看到,它会默认根据我们的输入的参数自动将变量代入,这个时候有人就会问了,使用了方法引用的比较器,比较出来的结果是升序还是降序啊。这里都给你安排好了。
Comparator<Integer> comparator = Integer::compareTo;
List<Integer> list = Arrays.asList(5,4,3,2,1);
list.sort(comparator);
System.out.println(list);
// 结果 [1, 2, 3, 4, 5]
可以看到,默认是升序的。
构造函数引用
能理解方法引用的话,构造函数的引用就比较好理解了,其实就是在创建对象的时候,这个对象是一个函数式接口,就可以使用构造函数引用,我们继续看代码。
这里会使用到Java
自带的一个函数式接口Supplier
// 原来
Supplier<Apple> supplier = new Supplier<Apple>() {
@Override
public Apple get() {
return new Apple();
}
};
// 构造函数引用
Supplier<Apple> supplier = Apple::new;
通过对比,相比大家也看到了lambda
表达式结合引用的优美表达,简化代码的同时又增强了代码的可读性。
配合函数式接口
随着lambda
特性一起来的其实还有很多函数式接口,大家如果想将lambda
玩的更加流畅的话,建议了解一下:
- Predicate ----> 提供了 test 方法,用来判断是否符合要求
- Consumer ----> 提供了 accept 方法,用来接收对象并进行消费
- Supplier -----> 提供了 get 方法,用来生产
- Function -----> 提供了 apply 方法,有返回有参数,可自行
diy
// Predicate ----> 提供了 test 方法,用来判断是否符合要求
private static void predicate() {
Predicate<String> predicate = (s) -> s.length() > 5;
System.out.println(predicate.test("holdonbei"));
}
// Consumer ----> 提供了 accept 方法,用来接收对象并进行消费
private static void consumer() {
Consumer<String> c1 = System.out::println;
c1.accept("Holdonbei");
}
// Supplier -----> 提供了 get 方法,用来生产
private static void supplier() {
Supplier<String> supplier = () -> "holdonbei";
System.out.println(supplier.get());
}
// Function -----> 提供了 apply 方法,有返回有参数,可自行`diy`
private static void function() {
Function<String, Integer> f = String::length;
}
除了这四个接口之外,JDK
还额外提供了其他接口,有兴趣的小伙伴可以自行了解哈~
类型推导
类型推导这块其实前面已经通过代码演示过了,在函数式接口中,我们的入参是可以提前确定的,比如:
Comparator<Integer> comparator = (n1, n2) -> n1 - n2;
由于前面已经在尖括号中给出了Integer
的说明,所以lambda
表达式中我们可以不再注明类型,Java
会自动给我们进行类型推导。
今天就到这里~
求知若饥,虚心若愚。我们下次再见~