前言
一、Lambda表达式
Lambda表达式是Java8的最重要的一点更新,其中涉及到了函数接口这个概念,先来简单看看用法。
在之前我们要为一个List做升序排序的时候,通常的写法是写成匿名内部类的方式
1 | List<Integer> list = Arrays.asList(4, 3, 5, 5, 1, 9, 6); |
用Lambda表达式简化过可以写成
1 | List<Integer> list = Arrays.asList(4, 3, 5, 5, 1, 9, 6); |
在上面的Lambda表达式中,Java编译器可以自动推导出参数类型,所以你可以不用再写一次类型。
之前提到了函数接口的概念,它允许我们将函数当成参数传递给某个方法,或者把代码本身当作数据处理。比如下面这段代码实现遍历的效果
1 | List<Integer> list = Arrays.asList(4, 3, 5, 5, 1, 9, 6); |
稍微复杂一些,如果需要遍历的是对象,可以写成下面这段。
1 | Student s1 = new Student("peter", "Beijing", 1); |
好了,回到之前的函数式接口的概念,Lambda之所以能在Java中使用,归功于Java中提供了一个@FunctionalInterface的注解。函数式接口就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口,那么就可以使用Lambda表达式来表示该接口的一个实现,其实就是匿名内部类的简化写法。比如上面的Comparator
1 |
|
(参数) -> 方法体的这种写法其实就是简化了匿名内部类的写法。
二、Stream接口
Stream多用于集合的计算,Stream 操作分为中间操作或者最终操作两种,最终操作返回一特定类型的计算结果,而中间操作返回Stream本身,这样你就可以将多个操作依次串起来。Stream 的创建需要指定一个数据源,比如 java.util.Collection的子类,List或者Set, Map不支持。Stream的操作可以串行执行或者并行执行。
集合接口有两个办法来生成流,stream()是生成串行流,parallelStream()是生成并行流。下面举几个例子
1 | List<Integer> list = Arrays.asList(4, 3, 5, 5, 1, 9, 6); |
比较复杂一些的例子有
1 | Student s1 = new Student("peter", "Beijing", 1); |
三、Optional接口
对于深度嵌套的语句,可能需要多次判空,才能保证代码的健壮性,但是用if来实现,会有一堆的if语句,java8通过optinal比较优雅的解决了这个问题。Optional是个用来防止NullPointerException异常的辅助类型,Optional 被定义为一个简单的容器,其值可能是null或者不是null。但是真正要发挥Optional能力的用法需要Optional和Lambda一起使用。
下面举例简单介绍。
1 | // 在之前写这种选择分支的语句我们通常会这么写 |
其中map和flatMap的区别是:
map中获取的返回值自动被Optional包装,即返回值 -> Optional<返回值>
flatMap中返回值保持不变,但必须是Optional类型,即Optional<返回值> -> Optional<返回值>