Java 8 新增了一个新的抽象称为流Stream,我的感受这个超级好用,尤为是业务开发,常常须要对数据列表进行处理的时候,用更少的代码、更优雅地实现功能。html
这个流式操做,更像是Linux中的管道命令'|',上一个操做的结果传送到下一个流程中继续处理,例如:java
+--------------------+ +------+ +------+ +---+ +-------+
| stream of elements +-----> |filter+-> |sorted+-> |map+-> |collect|
+--------------------+ +------+ +------+ +---+ +-------+
复制代码
在java代码实现linux
String content = "hello,world,debug,the,world";
List<String> list = Arrays.asList(content.split(","));
List<String> filter = list.stream()
.filter(temp -> temp.startsWith("w"))
.map(temp -> temp.substring(0, 3))
.collect(Collectors.toList());
filter.forEach(System.out::print);
复制代码
Stream(流)是一个来自数据源的元素队列并支持聚合操做git
和之前的Collection操做不一样,Stream还有两个基础特征:github
在Java8中,集合接口有两个方法生成流:数组
这里要讲一下这二者的区别:多线程
通俗点来讲,一个是单线程、另外一个是多线程。parallelStream是一个并行执行的流,经过默认的ForkJoinPool,能够提升多线程任务的速度。处理的过程会分而质之,将一个大任务切分红多个小任务,而后将结果合起来。(固然这也是一把双刃剑,在多线程的状况下,数据的并发访问须要关注,这也能够好好学一下,等以后再看吧~)并发
之前都是显示的使用循环,例如对一个集合进行打印: JDK7之前ide
for (int i = 0; i < list.size(); i++) {
String temp = list.get(i);
System.out.print(temp);
}
// 或者语法糖形式
for (String temp : list) {
System.out.print(temp);
}
复制代码
JDK8以后函数
list.forEach(System.out::println);
复制代码
对比一下,发现只须要一行代码就能实现~ 若是想在forEach中进行自定义的操做,能够建立一个类,实现Consumer函数接口,传递进去使用~
map方法用于映射每一个元素到对应的结果:
Car car1 = Car.create(Car::new, "小汽车1");
Car car2 = Car.create(Car::new, "小汽车2");
List<Car> carList = Lists.newArrayList(car1, car2);
List<String> nameList = carList.stream().map(Car::getName).collect(Collectors.toList());
// 还能够加入filter功能,先进行过滤,而后取出想要的字段组成新的列表
复制代码
Car类:
public class Car {
private Integer id;
private String name;
public static Car create(final Supplier<Car> supplier, String name) {
Car car = supplier.get();
car.setName(name);
return car;
}
public static void collide(final Car car) {
System.out.println("Collided " + car.toString());
}
public void follow(final Car another) {
System.out.println("Following the " + another.toString());
}
public void repair() {
System.out.println("Repaired " + this.toString());
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Car{}" + Thread.currentThread().getId() + getName();
}
}
复制代码
如其名,filter就是用来过滤的,根据特定的条件来过滤元素:
List<Integer> ints = Lists.newArrayList(1, 5, 6, 7, 10, 20, 31, 8, 9);
long count = ints.stream().filter(number -> number > 10).count();
System.out.println(count);
复制代码
上面的例子是用来过滤出整数列表中,值大于10的数量。
用来获取指定数量的流(相似于MySQL中的limit):
public void limitTest() {
List<Integer> ints = Lists.newArrayList(1, 5, 6, 7, 10, 20, 31, 8, 9);
ints.stream().limit(5).forEach(System.out::println);
}
复制代码
用来对流进行排序,相似于Collections.sort(list, Comparator);
List<Integer> ints = Lists.newArrayList(1, 5, 6, 7, 10, 20, 31, 8, 9);
ints.sort(Comparator.naturalOrder());
Car car1 = Car.create(Car::new, "小汽车1");
Car car2 = Car.create(Car::new, "小汽车2");
List<Car> carList = Lists.newArrayList(car1, car2);
// 能够自定义排序的字段,若是须要更复杂的排序规则,能够在lambda中的statement进行编写
carList.sort(Comparator.comparing(Car::getName));
复制代码
Collectors类实现了不少规约操做,例如将流转换成集合和聚合元素。(通常用Collectors.toList()就够了)
//例如在一组对象中或者主键ID的列表能够这样写
public void collectorsTest() {
List<Car> carList = Lists.newArrayList();
// 省略构建参数,获取列表中的主键ID列表
List<Integer> ids = carList.stream().map(Car::getId).collect(Collectors.toList());
}
复制代码
这个功能比较少用,仍是学习记录一下吧。
public void statisticsTest() {
List<Integer> ints = Lists.newArrayList(1, 5, 6, 7, 10, 20, 31, 8, 9);
IntSummaryStatistics statistics = ints.parallelStream().mapToInt(x -> (int) x).summaryStatistics();
System.out.println("最大值 : " + statistics.getMax());
System.out.println("最小值 :" + statistics.getMin());
System.out.println("平均值 :" + statistics.getAverage());
System.out.println("总和 : " + statistics.getSum());
System.out.println("数量 :" + statistics.getCount());
}
复制代码
package com.example.demo;
import com.example.demo.test.Car;
import com.google.common.collect.Lists;
import org.junit.Test;
import java.util.Arrays;
import java.util.Comparator;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.stream.Collectors;
/** * @author JingQ at 2019/1/31 */
public class JDK8StreamTest {
@Test
public void buildStreamTest() {
String content = "hello,world,debug,the,world";
List<String> list = Arrays.asList(content.split(","));
List<String> filter = list.stream()
.filter(temp -> temp.startsWith("w"))
.map(temp -> temp.substring(0, 3))
.collect(Collectors.toList());
filter.forEach(System.out::print);
}
@Test
public void forEachTest() {
String content = "hello,world,debug,the,world";
List<String> list = Arrays.asList(content.split(","));
list.forEach(System.out::println);
}
@Test
public void mapTest() {
Car car1 = Car.create(Car::new, "小汽车1");
Car car2 = Car.create(Car::new, "小汽车2");
List<Car> carList = Lists.newArrayList(car1, car2);
List<String> nameList = carList.stream().map(Car::getName).collect(Collectors.toList());
// 还能够加入filter功能,先进行过滤,而后取出想要的字段组成新的列表
}
/** * filter过滤 */
@Test
public void filterTest() {
List<Integer> ints = Lists.newArrayList(1, 5, 6, 7, 10, 20, 31, 8, 9);
long count = ints.stream().filter(number -> number > 10).count();
System.out.println(count);
}
/** * limit 限制数量 */
@Test
public void limitTest() {
List<Integer> ints = Lists.newArrayList(1, 5, 6, 7, 10, 20, 31, 8, 9);
ints.stream().limit(5).forEach(System.out::println);
}
@Test
public void sortedTest() {
List<Integer> ints = Lists.newArrayList(1, 5, 6, 7, 10, 20, 31, 8, 9);
ints.sort(Comparator.naturalOrder());
Car car1 = Car.create(Car::new, "小汽车1");
Car car2 = Car.create(Car::new, "小汽车2");
List<Car> carList = Lists.newArrayList(car1, car2);
// 能够自定义排序的字段,若是须要更复杂的排序规则,能够在lambda中的statement进行编写
carList.sort(Comparator.comparing(Car::getName));
}
@Test
public void collectorsTest() {
List<Car> carList = Lists.newArrayList();
// 省略构建参数,获取列表中的主键ID列表
List<Integer> ids = carList.stream().map(Car::getId).collect(Collectors.toList());
}
@Test
public void statisticsTest() {
List<Integer> ints = Lists.newArrayList(1, 5, 6, 7, 10, 20, 31, 8, 9);
IntSummaryStatistics statistics = ints.parallelStream().mapToInt(x -> (int) x).summaryStatistics();
System.out.println("最大值 : " + statistics.getMax());
System.out.println("最小值 :" + statistics.getMin());
System.out.println("平均值 :" + statistics.getAverage());
System.out.println("总和 : " + statistics.getSum());
System.out.println("数量 :" + statistics.getCount());
}
}
复制代码
JDK的流式处理真的是太方便了(虽然之前的代码能够显示的调用,但感受使用更少的代码来实现更加优雅😁)
但愿各位帮忙点个star,给我加个小星星✨