1. Lambda 表达式
2. 函数式接口
3. 方法引用与构造器引用
4. Stream API
5. 其他新特性
速度更快
代码更少(增加了新的语法 Lambda 表达式)
强大的 Stream API
便于并行
最大化减少空指针异常 Optional
Lambda 是一个匿名函数
在Java 语言中引入了一个新的语法元
素和操作符。这个操作符为 “->” , 该操作符被称
为 Lambda 操作符或剪头操作符。它将 Lambda 分为
两个部分:
左侧:指定了 Lambda 表达式需要的所有参数
右侧:指定了 Lambda 体,即 Lambda 表达式要执行
的功能。
语法格式一:无参,无返回值,Lambda 体只需一条语句
Runnable r1 = () → System.out.println("hello world");
语法格式二:Lambda 需要一个参数
Consumer
语法格式三:Lambda 只需要一个参数时,参数的小括号可以省略
Consumer
语法格式四:Lambda 需要两个参数,并且有返回值
BinaryOperator
System.out.println("hello world");
reurn x + y;
}
语法格式五:当 Lambda 体只有一条语句时,return 与大括号可以省略
BinaryOperator
语法格式六:数据类型可以省略,因为可由编译器推断得出,称为“类型推断”
BinaryOperator
System.out.println("hello world");
reurn x + y;
}
类型推断:
上述 Lambda 表达式中的参数类型都是由编译器推断
得出的。Lambda 表达式中无需指定类型,程序依然可
以编译,这是因为 javac 根据程序的上下文,在后台
推断出了参数的类型。Lambda 表达式的类型依赖于上
下文环境,是由编译器推断出来的。这就是所谓的
“类型推断”
(1) 只包含一个抽象方法的接口,称为函数式接口。
(2) 你可以通过 Lambda 表达式来创建该接口的对象。(若 Lambda
表达式抛出一个受检异常,那么该异常需要在目标接口的抽象方
法上进行声明)。
(3) 我们可以在任意函数式接口上使用 @FunctionalInterface 注解,
这样做可以检查它是否是一个函数式接口,同时 javadoc 也会包
含一条声明,说明这个接口是一个函数式接口。
@FounctionalInterface
public interface MyNumber {
public double getValue();
}
@FounctionalInterface
public interface MyNumber
public T getValue(T t);
}
ListenableFuture
函数式接 |
参数类型 |
返回类型 |
用途 |
---|---|---|---|
Consumer |
T | void | 对类型为T的对象应用操 作,包含方法: void accept(T t) |
Supplier |
无 | T | 返回类型为T的对象,包 |
Function |
T | R | 对类型为T的对象应用操作,并返回结果。结果是R类型的对象。包含方法:R apply(T t) |
Predicate |
T | boolea | 确定类型为T的对象是否满足某约束,并返回boolean 值。包含方法boolean test(T t) |
方法引用:使用操作符 “::” 将方法名和对象或类的名字分隔开来
对象::实例方法
类::静态方法
类::实例
Function
.stream().sorted(Comparator.comparingLong(ConditionAllVO::getStockTotalCount).reversed()).collect(Collectors.toList()))
是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列“集合讲的是数据,流讲的是计算
注意:
(1)Stream 自己不会存储元素。
(2)Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。
(3)Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行
Lists.newArrayList().stream() : 返回一个顺序流
Lists.newArrayList().parallelStream() : 返回一个并行流
Arrays.stream(new Integer[1]).count();
Stream stream = Stream.of(Lists.newArrayList());
多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止操作,
否则中间操作不会执行任何的处理!而在终止操作时一次性全部处理,称为“惰性求值”。
筛选
方 法 |
描述 |
---|---|
filter(Predicate |
接收 Lambda , 从流中排除某些元素。 |
distinct() | 筛选,通过流所生成元素的 hashCode() 和 equals() 去除重复 |
limit(long maxSize) | 截断流,使其元素不超过给定数 |
skip(long n) | 跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流。与 limit(n) 互补 |
映射
方 法 |
描述 |
---|---|
map(Function f) | 接收一个函数作为参数,该函数会被应用到每个素上,并将其映射成一个新的 |
mapToDouble(ToDoubleFunction f) | 接收一个函数作为参数,该函数会被应用到每个元 |
mapToInt(ToIntFunction f) | 接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 IntStream |
mapToLong(ToLongFunction f) | 接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 LongStream |
flatMap(Function f) flatMapToDouble(Function f) flatMapToInt(Function f) flatMapToLong(Function f) |
接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流 |
排序
方 法 |
描述 |
---|---|
sorted() | 产生一个新流,其中按自然顺序 |
sorted(Comparator comp) | 产生一个新流,其中按比较器顺序 |
查找与匹配
方 法 |
描述 |
---|---|
allMatch(Predicate p) | 检查是否匹配所有元素 |
anyMatch(Predicate p) | 检查是否至少匹配一个元素 |
noneMatch(Predicate p) | 检查是否没有匹配所有元素 |
findFirst() | 返回第一个元素 |
findAny() | 返回当前流中的任意元素 |
count() | 返回流中元素个数 |
max(Comparator c) | 返回流中最大值 |
min(Comparator c) | 返回流中最小值 |
forEach(Consumer c) | 内部迭代(使用 Collection 接口需要用户去做迭代,称为外部迭代。相反,Stream API 使用内部迭代——它帮你把迭代做了 |
归约
方 法 |
描述 |
---|---|
reduce(T iden, BinaryOperator b) |
可以将流中元素反复结合起来,得到一个值。返回 T |
reduce(BinaryOperator b) | 可以将流中元素反复结合起来,得到一个值。返回 Optional |
收集
方 法 |
描述 |
---|---|
collect(Collector c) | 将流转换为其他形式。接收一个 Collector接口的实现,用于给Stream中元素做汇总的方法 |
方法 |
返回类型 |
作用 |
---|---|---|
toList | List |
把流中元素收集到List:list.stream().collect(Collectors.toList()); |
toSet | Set |
把流中元素收集到Set:list.stream().collect(Collectors.toSet()); |
toCollection |
Collection |
把流中元素收集到创建的集合:list.stream().collect(Collectors.toCollection(ArrayList::new)); |
counting | Long | 计算流中元素的个数:list.stream().collect(Collectors.counting()); |
summingInt | Integer | 对流中元素的整数属性求和:list.stream().collect(Collectors.summingInt(类名::属性名)); |
averagingInt | Double | 计算流中元素Integer属性的平均值:list.stream().collect(Collectors.averagingInt(类名::属性名)); |
summarizingInt summarizingLong summarizingDouble |
IntSummaryStatistics | 收集流中Integer属性的统计值:list.stream().collect(Collectors.summarizingInt(类名::属性名)); 一次性得到元素个数、总和、均值、最大值、最小值 |
joining |
String | 连接流中每个字符串: |
maxBy |
Optional |
根据比较器选择最大值: list.stream().collect(Collectors.maxBy(comparingInt(类名::属性名))); |
minBy | Optional |
根据比较器选择最小值:list.stream().collect(Collectors.minBy(comparingInt(类名::属性名)) |
reducing | 归约产生的类型 | 从一个作为累加器的初始值开始,利用BinaryOperator与流中元素逐个结合,从而归约成单个值 list.stream().collect(Collectors.reducing(0, 类名::属性名, Integer::sum)); |
collectingAndThen | 转换函数返回的类型 | 包裹另一个收集器,对其结果转换函数:list.stream().collect(Collectors.collectingAndThen(Collectors.toList(), List::size)); |
groupingBy 根据 | Map |
某属性值对流分组,属性为K,结果为V: list.stream().collect(Collectors.groupingBy( 类名::属性名)); |
partitioningBy | Map |
根据true或false进行分区:list.stream().collect(Collectors.partitioningBy(类名::属性名) |
并行流就是把一个内容分成多个数据块,并用不同的线程分
别处理每个数据块的流。
Java 8 中将并行进行了优化,我们可以很容易的对数据进行并
行操作。Stream API 可以声明性地通过 parallel() 与
sequential() 在并行流与顺序流之间进行切换。
Optional
原来用 null 表示一个值不存在,现在 Optional 可以更好的表达这个概念。并且
可以避免空指针异常。
常用方法:
Optional.of(T t) : 创建一个 Optional 实例
Optional.empty() : 创建一个空的 Optional 实例
Optional.ofNullable(T t):若 t 不为 null,创建 Optional 实例,否则创建空实例
isPresent() : 判断是否包含值
orElse(T t) : 如果调用对象包含值,返回该值,否则返回t
orElseGet(Supplier s) :如果调用对象包含值,返回该值,否则返回 s 获取的值
map(Function f): 如果有值对其处理,并返回处理后的Optional,否则返回 Optional.empty()
flatMap(Function mapper):与 map 类似,要求返回值必须是Optional
QQ学习交流,资料共享群:696647351,期望大家一起学习讨论