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,給我加個小星星✨