大家好,又见面了,我是全栈君。
了解Stream
Java8中有两个最为重要的改变,一个是Lambda表达式,另一个就是Stream API,针对常见的集合数据处理,Stream API 提供了一种高效且易于使用的数据处理方式。
什么是Stream
基本概念
流(Stream)用于操作数据源所生成的元素序列。Java 8给Collection接口增加了两个默认方法,它们可以返回一个Stream
default Stream stream() { return StreamSupport.stream(spliterator(), false); }//stream()返回的是一个顺序流 default Stream parallelStream() { return StreamSupport.stream(spliterator(), true); }//parallelStream()返回的是一个并发流
- Stream 自己不会存储元素。
- Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。
- Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。
基本示例
首先这里有一个Employee类
代码语言:java复制public class Employee {
private int id;
private String name;
private int age;
private double salary;
/*省略getter setter Constructor*/
}复制代码
代码语言:java复制//Employee列表
List<Employee> emps = Arrays.asList(
new Employee(102, "李四", 59, 6666.66),
new Employee(101, "张三", 18, 9999.99),
new Employee(103, "王五", 28, 3333.33),
new Employee(104, "赵六", 20, 7777.77),
new Employee(104, "赵六", 19, 7777.77),
new Employee(104, "赵四", 40, 7777.77),
new Employee(105, "田七", 38, 5555.55)
);复制代码
返回薪资大于5000的员工列表,java8以前是这样做的
代码语言:java复制List<Employee> newEmps = new ArrayList<>();
for(Employee emp : emps){
if(emp.salary > 5000.00){
newEmps.add(emp);
}
}复制代码
使用Stream API ,代码可以这样
代码语言:java复制List<Employee> newEmps = emps.stream()
.filter(s -> s.getSalary() > 5000.00)
.collect(Collectors.toList());复制代码
先通过stream()得到一个Stream对象,然后调用Stream上的方法,filter()过滤得到薪资大于5000的,它的返回值依然是一个Stream,然后通过调用collect()方法并传递一个Collectors.toList()将结果集存放到一个List中.
使用Stream API处理集合类代码更加简洁易读.
下面介绍一下Stream中的两种操作
Stream的中间操作和终止操作
中间操作:
多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何的处理!而在终止操作时一次性全部处理,称为“惰性求值”
方法 | 描述 |
---|---|
filter(Predicate p) | 接收 Lambda , 从流中排除某些元素。 |
distinct() | 筛选,通过流所生成元素的 hashCode() 和 equals() 去 |
limit(long maxSize) | 截断流,使其元素不超过给定数量。 |
map(Function f) | 接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。 |
flatMap(Function f) | 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流 |
sorted(Comparator comp) | 产生一个新流,其中按比较器顺序排序 |
sorted() | 产生一个新流,其中按自然顺序排序 |
终止操作:
终端操作会从流的流水线生成结果。其结果可以是任何不是流的值,例如:List、Integer,甚至是void 。
方法 | 描述 |
---|---|
forEach(Consumer c) | 内部迭代 |
collect(Collector c) | 将流转换为其他形式。接收一个 Collector接口的实现,用于给Stream中元素做汇总的方法 |
max(Comparator c) | 返回流中最大值 |
min(Comparator c) | 返回流中最小值 |
count() | 返回流中元素总数 |
收集 : collect(Collector c)方法需要一个Collector 作为参数,Collector 接口中方法的实现决定了如何对流执行收集操作(如收集到 List、Set、Map)。Java8中提供了一个Collectors工具类, 工具中提供了很多静态方法,可以方便地创建常见收集器例
具体方法与实例如下表
方法 | 返回类型 | 作用 |
---|---|---|
toList | List | 把流中元素收集到List |
toSet | Set | 把流中元素收集到Set |
toCollection | Collection | 把流中元素收集到创建的集合 |
groupingBy | Map> | 根据某属性值对流分组,属性为K,结果为V |
partitioningBy | Map> | 根据true或false进行分区 |
这里只列出了一些常用的方法.具体参考Java8 Stream API : Java Platform SE 8
Stream API 使用
中间操作
终止操作
输出结果为: 田:[Employee [id=105, name=田七, age=38, salary=5555.55] 张:[Employee [id=101, name=张三, age=18, salary=9999.99] 赵:[Employee [id=104, name=赵六, age=20, salary=7777.77], Employee [id=104, name=赵六, age=19, salary=7777.77], Employee [id=104, name=赵四, age=40, salary=7777.77]] 王:[Employee [id=103, name=王五, age=28, salary=3333.33] 李:[Employee [id=102, name=李四, age=59, salary=6666.66]
Optional 类
介绍
Optional 容器类:用于尽量避免空指针异常
方法
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
小结
Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。也可以使用 Stream API 来并行执行操作。 简而言之,Stream API 提供了一种高效且易于使用的处理数据的方式
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/108115.html原文链接:https://javaforall.cn