lambda ->
左边 参数列表 对应接口中方法的参数列表
右边 功能实现 对应方法的实现
来代替匿名内部类
需要函数式接口的支持,若接口中只有一个抽象方法的接口。称为函数式接口
右边使用同级别变量时,有final 修饰 ,跟匿名内部类(默认加上final)一样,其实就是语法糖 1.7之前不默认加 ,需要自己显式加上
格式1:无参数,无返回值
runnable接口
()->sout(“hello”)
格式2:有 参数,无返回值 只有一个参数的话 小括号可以省略
Consumer接口
Consumer con = (x)->sout(x);
格式3:有多个参数,有返回值,有多条语句(必须大括号括起来)
格式4:若lambda只有一条语句,return 和大括号都可以不写
lambda表达式需要函数式接口的支持。java内置了一些,不用我们自己创建了
四大核心函数式接口:
- Consumer :消费型接口
void accept(T t); - Supplier : 供给型接口
T get(); - Function<T,R>:函数型接口
R apply(T t) - predicate 断言型接口
boolean test(T t)
方法引用
若lambda体中的内容有方法已经实现了,我们可以“方法引用”(可以理解为lambda的另一种表现形式)
三种格式:
对象:: 实例方法名
类::静态方法名
类::实例方法名
//就是简化了 lambda的书写
public class TestLambda {
public static int operation(int x, Function<Integer,Integer> function){
return function.apply(x);
}
public static void main(String[] args) {
System.out.println(operation(-100,Math::abs));//这种用法,引用的方法和函数式接口中的抽象方法的参数和返回值得一致
//System.out.println(operation(-100,(x)->Math.abs(x)));
}
}
构造器引用
格式: classname::new
需要调用构造器的参数列表要与函数式接口中抽象方法的参数列表保持一致。
Stream
是类似io流的数据渠道。用于操作数据源所生成的元素序列
集合讲的是数据,流讲的是计算
stream 自己不会存储元素
stream不会改变源对象,会返回一个持有结果的新流
stream操作是延迟的,会等到需要结果时候才执行
步骤:
1.创建 stream流
- 通过 Collection集合提供的stream()或parallelStream()
- 通过Arrays中的静态方法stream()获取数组流。
- 通过stream类中的静态方法of();
- 创建无限流 Stream stream = Stream.iterate(0,(x)->x+2); //迭代,无限的
Stream.generate(()->Math.random())//生成
2.中间操作
- 筛选与切片
filter–接收lambda,从流中排除某些元素
limit–截断流,使其元素不超过给定数量
skip–跳过元素,返回扔掉前n个元素的流,与limit互补
distinct–筛选,通过流的元素的hashcode()和equals()去除重复元素。 所以要重写hashcode和 equals - 映射
map-- 接收lambda,将元素装换成其他形式或提取信息,接收一个函数作为参数,该函数被应用到每一个元素上,并将其映射成一个新的元素。
flatMap–接收函数作为参数,将流中的每一个值都换成另一个流,然后把所有流连接成一个流。 - 排序
sorted–自然排序
sorted(comparator com)–定制排序
3.终止操作
- 查找与匹配
allmatch–是否匹配所有元素
anymatch–最少一个元素
nonematch–是否没有匹配所有元素
findfirst–返回第一个元素
findany–返回任意一个
count–返回总个数
max–最大值
min–最小值 - 归约与收集
reduce(T iden, BinaryOperator b)/reduce(BinaryOperator b)-- 可以将流中元素反复结合起来,得到一个值。
collect-- 接收一个collector接口的实现
parallel
并行流,底层是fork join框架。简化了使用。