Java8 Lambda表达式知识点汇总

Lambda的相关内容可以查看之前的文章,已经有30多篇相关讲解的内容,在本站内搜索“lambda从入门到精通”,可以查看Lambda相关课程。
http://www.itzhimei.com/archives/tag/lambda%e4%bb%8e%e5%85%a5%e9%97%a8%e5%88%b0%e7%b2%be%e9%80%9a。
接下来对Lambda的知识点进行概括。

Java的Lambda表达式的优点:
一是简化代码,让编写更流程;
二是将函数变为了一等公民,能像变量一样传递;
三是对并行的支持。

体验Lambda
Lambda Hello World

函数式接口
一个接口中只定义了一个方法,那么这个接口称为函数式接口

行为参数化
函数变为Java中的一等公民

异常处理
一种是受检异常,一种是非受检异常

类型检查和类型判断
我们所写的任何lambda表达式,都要有对应的函数式接口的抽象方法与之对应。也就是说lambda的入参和返回值,要和函数式接口的抽象方法定义的入参和返回值相匹配。只有有对应的函数式接口抽象方法,才能使用对应的lambda表达式。

方法引用
实例上的实例方法引用 instanceReference::methodName
父类实例方法引用 super::methodName
类型上的实例方法引用 ClassName::methodName
构造方法引用 Class::new
数组构造方法引用 TypeName[]:new
静态方法 ClassName::methodName

复合lambda表达式
所谓的复合lambda表达式,就是多个lambda表达式可以组合在一起使用。
lambda的这种复合分为两种,一种是谓词复合,另一种是函数复合。

Java8中常用函数式接口:
Predicate
抽象方法
boolean test(T t);
谓词(predicate) 在数学上常常用来代表一个类似函数的东西,它接受一个参数值,并返回true或false
函数描述符
T->boolean
原始类型–函数式接口
IntPredicate
LongPredicate
DoublePredicate
Consumer
抽象方法
void accept(T t);
函数描述符
T->void
原始类型–函数式接口
InttConsumer
LongtConsumer
DoubletConsumer
Function
抽象方法
R apply(T t);
函数描述符
T->R
原始类型–函数式接口
IntFunction, IntToDoubleFunction, IntToLongFunction, LongFunction, LongToDoubleFunction, LongToIntFunction, DoubleFunction, ToIntFunction, ToDoubleFunction, ToLongFunction
Supplier
抽象方法
函数描述符
()->T
原始类型–函数式接口
BooleanSupplier, IntSupplier, LongSupplier, DoubleSupplier
UnaryOperator
抽象方法
R apply(T t);
函数描述符
T->R
原始类型–函数式接口
IntUnaryOperator, LongUnaryOperator, DoubleUnaryOperator
BinaryOperator
抽象方法
函数描述符
(T,T)->T
原始类型–函数式接口
IntBinaryOperator, LongBinaryOperator, DoubleBinaryOperator
BiPredicate
抽象方法
函数描述符
(L,R)->boolean
原始类型–函数式接口

BiConsumer
抽象方法
函数描述符
(T,U)->void
原始类型–函数式接口
ObjIntConsumer, ObjLongConsumer, ObjDoubleConsumer
BiFunction
抽象方法
函数描述符
(T,U)->R
原始类型–函数式接口
ToIntBiFunction, ToLongBiFunction, ToDoubleBiFunction

流-stream
流的特点:一个是流是内部迭代,另一个是流的按需计算。

流的操作
流的操作分为两种:中间操作和终端操作。

中间操作:可以连起来的操作,中间操作会返回另一个流,除非流水线上触发一个终端操作,否则中间操作不会执行任何处理,因为中间操作一般都可以合并起来,在终端操作时一次性全部处理。

终端操作:关闭流的操作,终端操作会从流的流水线生成结果。生成的结果是任何不是流的值,比如List、Integer等。

流的使用–映射map、flatMap

流的使用–筛选filter、distinct、skip、limit

流的使用-查找与匹配allMatch、anyMatch、noneMatch、findAny、findFirst

流的使用-规约
在实际应用中,我们经常要用到将一组数据的值进行累加汇总,得到一个总和,lambda中也支持这样的操作,就是reduce()函数。
当然,规约的概念并不是仅限于求和,凡是要将一组值合起来,再求出一个值的操作,都是规约,比如我求最大值、最小值等。

reduce求和    
    T reduce(T identity,BinaryOperator<T> accumulator)

求最大最小值
    用reduce也可以去最大和最小值,这里先看最大值:
    Optional<Double> max = list.stream().map(Student::getMath).reduce(Double::max);

    Stream中也实现了一个max方法,可以直接求最大值:
    Optional<Student> max2 = list.stream().max(Comparator.comparing(Student::getMath));

流的使用-创建流
流的创建主要分为四种:
由值创建流
Stream.of()
Stream stream = Stream.of(“Java”, “Lambda “); stream.map(String::toUpperCase).forEach(System.out::println);
由数组创建流
Arrays.stream()
int[] numbers = {1,2, 3, 4, 5,}; int sum = Arrays.stream(numbers).sum();
由文件生成流
Stream lines(Path path)
由函数生成流:创建无限流
Stream.iterate和Stream.generate
iterate
iterate方法接受一个初始值(在这里是0),还有一个依次应用在每个产生的新值上的Lambda(UnaryOperator类型)
generate
接受一个Supplier类型的Lambda提供新的值

流的使用-数值流
Java8除了提供了Stream之外,还提供了三种基础流IntStream、 DoubleStream和LongStream,基础流的最重要的作用就是避免装箱和拆箱造成的性能损耗。

装箱拆箱使用如下:
    映射到数值流(拆箱)
    mapToInt()
    int calories = menu.stream().mapToInt(Dish::getCalories).sum();
    转回对象流(装箱)
    boxed()
    IntStream intStream = menu.stream().mapToInt(Dish::getCalories); Stream stream = intStream.boxed();
    注意数值流的空,数值流的空是对应类型的默认值,这时候要使用对应Option
    OptionalInt、OptionalDouble和OptionalLong

收集器Collectors API总结
Collectors收集器,提供了大量的静态方法对流进行操作
单一求值
求和
summingDouble(ToDoubleFunction mapper)
summingInt(ToIntFunction mapper)
summingLong(ToLongFunction mapper)
求数量
counting()
求平均
averagingDouble(ToDoubleFunction mapper)
averagingInt(ToIntFunction mapper)
averagingLong(ToLongFunction mapper)
求最大值
maxBy(Comparator comparator)
求最小值
minBy(Comparator comparator)
求值工厂:一次性求和、求数量、求平均、最大、最小值
summarizingDouble(ToDoubleFunction mapper)
summarizingInt(ToIntFunction mapper)
summarizingLong(ToLongFunction mapper)
拼接
joining()
分组
groupingBy(Function classifier)
分区
partitioningBy(Predicate predicate)
规约
reducing(BinaryOperator op)
映射
toCollection(Supplier collectionFactory)
toConcurrentMap(Function keyMapper, Function valueMapper)
toList()
toMap(Function keyMapper, Function valueMapper)
toSet()
mapping(Function mapper, Collector downstream)

自定义收集器Collectors
collect()方法中我们之前用的最多的就是toList()方法,还可以使用如下的映射方法:

toCollection(Supplier collectionFactory)
toConcurrentMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper)
toList()
toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper)
toSet()
mapping(Function<? super T,? extends U> mapper, Collector<? super U,A,R> downstream)

并行流-parallel()方法
LongStream.rangeClosed(1, 100000L).parallel()

Optional类
Optional类是一个容器类,代表一个值存在或不存在,这一个特性就可以帮助我们解决Java程序员最常见的空指针问题。
isPresent()
get()
orElse()
map()
flatMap()

Future异步编程

CompletableFuture异步编程
CompletableFuture相较于Future,更能更加强大,CompletableFuture的出现就是为了解决Future的不足才设计的。
CompletableFuture能够非常容易地将多个计算任务以同步或异步方式执行,并将任务结合到一起,实现多个异步计算的关联计算等复杂功能。

串联计算
thenApply
thenCompose

并行计算
thenCombine