Open xinrong2019 opened 5 years ago
只有一个方法的接口,称为函数式接口。
可以通过Lambda表达式来创建函数接口的对象。
Lambda表达式的实例是一个函数式接口的实例。
只要一个对象是函数式接口的实例,就可以用Lambda表达式来表示。
Java8中,Lambda表达式是对象,不是函数,必须依赖函数式接口。
FunctionalInterface注解可以用来检验函数式接口,类似于Overide注解的作用。
Consumer<T>
参数类型:T
返回类型:void
用途:对类型为T的对象操作,包含方法:void accept(T t)
Supplier<T>
参数类型:无
返回类型:T
用途:返回类型为T的对象,包含方法:T get()
Function<T,R>
参数类型:T
返回类型:R
用途:对类型为T的对象应用操作,并返回结果。结果是R类型的对象。包含方法:R apply(T t)
Predicate<T>
参数类型:T
返回类型:boolean
用途:确定类型为T的对象是否满足某约束,并返回boolean值,包含方法:boolean test(T t)
方法引用是一种特殊的Lamba表达式
也是函数式接口的一个实例,通过方法的名字来指向一个方法。
实例接口的抽象方法的参数列表和返回值类型,必须与方法引用的方法参数列表和返回值类型保持一致
1、对象::实例方法名
2、类::静态方法名
3、类::实例方法名
Consumer中的void accept(T t) PrintStream中的void println(T t)
Comparator中的int compare(T t1,T t2) Integer中的int compare(T t1,T t2)
Function中的R apply(T t) Math中的Long round(Double d)
Comparator中的int compare(T t1,T t2) String中的int t1.compareTo(t2)
BiPredicate中的boolean test(T t1,T t2) String中的boolean t1.equals(t2)
Function中的R apply(T t) Employee中的String getName()
Supplier中的T get() Employee的无参构造器:Employee
Supplier
Function中的R apply(T t)
BiFuntion中的R apply(T t,U u)
构造器引用和方法引用类似,只要有匹配的函数式接口的形参列表和构造器的形参列表一样,就可以使用。
抽象方法的返回值类型即为构造器所属的类的类型。
Function<Integer,String[]> func = String[] :: new;
Stream是有关计算的,关注的时运算,面向CPU。
Stream自己不会存储元素
Stream不会改变源对象。
Stream操作时延迟执行的,这意味着他们会等到需要结果的时候才行。
1、创建Stream
2、中间操作
3、终止操作
终止操作时,执行中间操作,并产生结果,之后不会再被使用
集合,通过集合的stream()方法
数组,通过Arrays.stream(数组)
通过Stream.of()创建Stream
创建无限流,造数据(了解)
迭代
Stream.iterate(0,t ->t + 2).limit(10).forEach(System.out::println);
生成
Stream.generate(Math::random).limit(10).forEach(System.out::println);
filter(Predocate p)
limit(n)
skip(n),跳过前n个
distinct()通过流所生成元素的hashCode()和equals()去除重复元素
操作流中每个元素
将流中的每个值换成另一个流,然后将所有流连接成一个流,类似于集合的addAll方法。
产生一个新流,按自然顺序排序
产生一个新流,其中按比较器排序
从流的流水线上生成结果。
检查是否匹配所有元素,集合为空,返回true(有点坑,注意使用)
检查是否至少匹配一个元素
检查是否没有匹配所有元素
返回optinal类型
返回第一个元素
返回当前流中的任意元素
返回long类型
max(Comparator c)
min(Comparator c)
forEach(Comsumer c)
传入一个消费者,数据必须时从参数带来的
生产者:自己生产数据
可以将流中元素反复结合起来,得到一个值,返回T。
T是初始值,BinaryOperator是反复操作
可以将流中元素反复结合起来,得到一个值。返回Optional
1、计算1-10的自然数的和
2、计算公司所有员工工资的总和。
将流收集为List、Set、Map
collect(Collectors.toList())
toList
toSet
toCollection
counting
summingInt
对流中元素的整数属性求和
averagingInt
计算流中元素Integer属性的平均值
summarizingInt
收集流中Integer属性的统计值。如:平均值
Optional
可以理解为对null的一个包装,是面向对象的设计。类似与包装类对基本数据类型的包装。
创建Optional类对象的方法:
Optional.of(T t):创建一个Optional实例,t必须非空
Optional.empty():创建一个空的Optional实例
Optional.ofNullable(T t):t可以为null
判断Optional容器中是否包含对象:
boolean isPresent():判断是否包含对象
void ifPresent(Consumer<? super T> consumer):如果有值,就执行Consumer接口的实现代码,并且该值会作为参数传给它
获取Optional容器的对象:
T get()
如果调用对象包含值,返回该值,否则抛异常
T orElse(T other)
如果有值则将其返回,否则返回指定的other对象。
T orElseGet(Supplier<? extends T> other)
如果有值返回,否则返回由Supplier接口实现提供的对象。
T orElseThrow(Supplier<? extends X> exceptionSupplier)
如果有值返回,否则抛出由Supplier接口实现提供的异常
不够优雅的代码:
if(boy != null){
Girl girl = boy.getGirl();
if(girl != null){
return girl.getName();
}
}
优雅的写法
Optional<Boy> boyOptional = Optional.ofNullable(boy);
Boy boy1 = boyOptional.orElse(new Boy(new Girl("张三")));
Girl girl = boy1.getGirl();
Optional<Girl> girlOptional = Optional.ofNullable(girl);
Girl girl1 = girlOptional.orElse(new Girl("李思思"));
把ifelse代码转换为可读性更好的方法
1、Lambda表达式
2、函数式接口
3、方法引用和构造器引用
4、Stream API
5、Optional类
学习的思维方式:
1、大处着眼,小处着手
2、逆向思维、反证法
3、透过问题看本质
4、小不忍则乱大谋
5、识时务者为俊杰
6、学思结合
Java8新特性
速度更快
代码更少(新语法:Lambda)
强大的Stream API
便于并行
最大化减少空指针异常:Optional
Nashorn引擎,允许在JVM上运行JS应用
jjs.exe