一、Lambda表达式
1、语法
例:比较俩个数
Comparator<Integer> com=(x,y)—>Integer.compare(x,y);
TreeSet<Integer> ts=new TreeSet<>(com);
lambda操作符 ”—>"
左侧:lambda表达式的参数列表
右侧:表达式中所需执行的功能;
语法:
语法格式一:无参数,无返回值。
()——>System.out.println("hello Lambda");
语法格式二:一个参数,无返回值。
(x)——>System.out.println(x);
语法格式三:2个以上的参数,lambda体中多条语句,有返回值。
Comparator<Integer> com = (x,y)->{
System.out.println("函数式接口");
return Integer.compare(x,y); }
语法格式四:如果只有一条语句,大括号和return都可以一省略不写。
Comparator<Integer> com=(x,y)->System.out.println("函数式接口")
语法格式五:Lambda表达式参数列表的数据类型可省略不写,java编译器可根据上下文推断出类型。
2、Java8中内置的四大核心函数式接口
函数式接口:接口中只有一个抽象方法时,被称为函数式接口,Java中被@FunctionalInterface修饰的接口可以检查该接口是否是一个函数式接口,同时javadoc也会包含一条声明,说明这个接口是一个函数式接口。
- Consumer:消费型接口void accept(T t);
- Supplier:供给型接口T get();
- Function<T,R>:函数型接口R apply(T t);
- Redicate:断言型接口boolean test(T t);
作为参数传递Lambda表达式:为了将Lambda表达式作为参数传递,接受Lambda表达式的参数类型必须是与该Lambda表达式兼容的函数式接口的类型。
3、方法引用
若lambda体中的内容有方法已经实现了,我们可以使用方法引用。
语法格式:
1>对象::实例方法名
Consumer con=(x)->System.out.println(x);
转化:Consumer con=System.out::println
2>类::静态方法名
Comparator com=(x,y)->Integer.compare(x,y);
转化:Comparator com=Integer::compare;
3>类::实例方法名
Bipredicate<String,String> bp=(x,y)->x.equals(y);
转化:Bipredicate<String,String> bp=String::equals;
若lambda参数列表中的第一个参数时实例方法的调用者,而第二个参数是实例方法的参数时,使用此语法。
4、构造器引用
格式:ClassName::new
1>无参构造器Supplier sup=()->new Employee();
转化Supplier sup=Employee::new;
2>一个参数构造器
Function<Integer,Empolyer> fum=(x)->new Emmployer(x);
转化Function<Integer,Empolyer> fum=Emmployer::new;
注意:需要调用的构造器的参数列表要与函数式接口中抽象方法的参数列表保持一致。
5、数组引用
格式:Type::new;
Function<Integer,String[]> fun=(x)->new String[x];
转化:Function<Integer,String[]> fun=String[]::new;
二、Stream API
1、基本定义
流:是数据渠道,用于操作数据源(集合/数组等)所生成的元素序列。”集合讲的是数据,流讲的是计算“
注意:
Stream自己不会存储元素。
Stream不会改变源对象,会返回一个持有结果的新Stream。
Stream操作时延迟执行的。
步骤:创建Stream/中间操作/终止操作
中间操作:
1》筛选与切片
filter(Predicate p):接收lambda,从流中排除某些元素。
distinct(): 筛选通过流所生成元素的hashCode()和equals()去除重复元素。
limit(Long n): 截断流,使其元素不超过给定数量。
skip(Long n): 跳过元素,返回一个扔掉了前n个元素的流。若流中元素不足n个,则返回一个空流。与limit(n)互补。
2》映射
map:接收lambda将元素转换成其他形式或提取信息。接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新函数。
flatMap:接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连成一个流。
3》排序
sorted():自然排序
sorted(Comparator com): 定制排序
终止操作:
1》查找与匹配
allMatch:检查是否匹配所有元素,返回Boolean。
anyMatch:检查是否至少匹配一个元素,返回Boolean。
noneMatch:检查是否没有匹配所有元素,返回Boolean。
findFirst:返回第一个元素,形成Optional<>容器。
count:返回流中元素的总个数。
max:返回流中最大值。
min:返回流中最小值。
2》规约
reduce(T identity, BinaryOperator) 返回基本类型,第一个参数是起始值,第二个参数为一个二元运算。
reduce(Binary Operator)返回Optionalreduce可以将流中元素反复结合起来,得到一个值。
3》收集
collect:将流转换为其他形式,手机一个collector接口的实现,用于给stream中元素做汇总方法。
2、java8中并行流与顺序流
Fork/Join框架:在必要情况下,将一个大任务进行拆分(fork)成若干个小人物(拆到不可再拆时),再将一个个小任务压入到线程队列,将小任务的运行结果进行join汇总。
例:计算0到10000000000L的累加
原来顺序流:LongStream.rangeClost(0,10000000000L).reduce(0,Long::sum);
并行流:LongStream.rangeClose(0,10000000000L).parallel().reduce(0,Long::sum);
并行流:把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流,Java8中将并行流进行优化,可以很容易的对数据进行并行操作。Stream API可以声明性的通过parallel()与 sequential() 在并行流与顺序流之间进行切换。
三、接口中的默认方法和静态方法默认
方法在接口中拥有实现的方法称为默认方法,用default修饰。
Public interface MuFun{
default String getName() {return "123"}
}
一个普通类实现两个接口或继承一个类并实现一个接口。若一个接口中定义了一个默认方法,而另外一个父类或接口中 又定义了一个同名的方法时:
1》选择父类中的方法。如果一个父类提供了具体的实现,那么 接口中具有相同名称和参数的默认方法会被忽略。
2》 接口冲突。如果一个父接口提供一个默认方法,而另一个接 口也提供了一个具有相同名称和参数列表的方法(不管方法 是否是默认方法),那么必须覆盖该方法来解决冲突。
静态方法
Public interface MuFun{
Public static void show(){System.out.println("接口中的静态方法");}
}