流操作可以分为两类:中间操作和终端操作
中间操作:又可以分为有状态和无状态两种
定义:一个流可以后面跟随零个或多个中间操作。其目的主要是打开流,做出某种程度的数据映射/过滤,然后返回一个新的流,交给下一个操作使用。这类操作都是惰性化的(lazy),就是说,仅仅调用到这类方法,并没有真正开始流的遍历。
终端操作:又可以分为短路和非短路两种
定义: 一个流只能有一个终端操作,当这个操作执行后,流就被使用“光”了,无法再被操作。所以这必定是流的最后一个操作。终端操作的执行,才会真正开始流的遍历,并且会生成一个结果。
中间无状态操作:
可以在单个对单个的数据进行处理。比如:filter(过滤)一个元素的时候,也可以判断,比如map(映射)、filter(过滤)、flatmap(扁平化)、peek(遍历每一个元素)
过滤 filter:过滤掉不符合要求的元素
映射 map:将一个元素转化为另一个元素,比如:将Integer型的对象转换为String型的对象
public void mapTest() {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.stream()
.map(e-> e.toString)
.forEach(item ->
System.out.println(item)));
}
扁夹化 flatMap:将一个对象转换成流
@Test
public void flatMapTest() {
list.stream()
// flatMap
.flatMap(sku -> Arrays.stream(
sku.getSkuName().split("")))
.forEach(item ->
System.out.println(
JSON.toJSONString(
item, true)));
}
遍厉 peek:对流中元素进行遍历操作,与forEach类似,但不会销毁流元素
public void peek() {
list.stream()
// peek
.peek(sku -> System.out.println(sku.getSkuName()))
.forEach(item ->
System.out.println(
JSON.toJSONString(
item, true)));
}
中间有状态操作:
是在所有的数据基础上进行操作的。比如:去重 distinct、跳过 skip、排序 sorted、截断 limit
去重 distinct
/**
* distinct使用:对流元素进行去重。有状态操作
*/
@Test
public void distinctTest() {
list.stream()
.map(sku -> sku.getSkuCategory())
// distinct
.distinct()
.forEach(item ->
System.out.println(
JSON.toJSONString(
item, true)));
}
跳过 skip
/**
* skip使用:跳过前N条记录。有状态操作
*/
@Test
public void skipTest() {
list.stream()
.sorted(Comparator.comparing(Sku::getTotalPrice))
// skip
.skip(3)
.forEach(item ->
System.out.println(
JSON.toJSONString(
item, true)));
}
截断 limit
/**
* limit使用:截断前N条记录。有状态操作
*/
@Test
public void limitTest() {
list.stream()
.sorted(Comparator.comparing(Sku::getTotalPrice))
.skip(2 * 3)
// limit
.limit(3)
.forEach(item ->
System.out.println(
JSON.toJSONString(
item, true)));
}
排序 sorted
/**
* sort使用:对流中元素进行排序,可选则自然排序或指定排序规则。有状态操作
*/
@Test
public void sortTest() {
list.stream()
.peek(sku -> System.out.println(sku.getSkuName()))
//sort
.sorted(Comparator.comparing(Sku::getTotalPrice))
.forEach(item ->
System.out.println(
JSON.toJSONString(
item, true)));
}
终端短路操作:
对流中的元素进行判断、取值等操作,当流中的某个或多个元素符合操作条件时,操作结束,不对流中剩下的元素做操作。
/**
* allMatch使用:终端操作,短路操作。所有元素匹配,返回true
*/
@Test
public void allMatchTest() {
boolean match = list.stream()
.peek(sku -> System.out.println(sku.getSkuName()))
// allMatch
.allMatch(sku -> sku.getTotalPrice() > 100);
System.out.println(match);
}
/**
* 找到第一个
*/
@Test
public void findFirstTest() {
Optional<Sku> optional = list.stream()
.peek(sku -> System.out.println(sku.getSkuName()))
// findFirst
.findFirst();
System.out.println(
JSON.toJSONString(optional.get(), true));
}
终端非短路操作:
与短路操作相比,会遍历所有的元素
/**
* anyMatch使用:任何元素匹配,返回true
*/
@Test
public void anyMatchTest() {
boolean match = list.stream()
.peek(sku -> System.out.println(sku.getSkuName()))
// anyMatch
.anyMatch(sku -> sku.getTotalPrice() > 100);
System.out.println(match);
}
/**
* noneMatch使用:任何元素都不匹配,返回true
*/
@Test
public void noneMatchTest() {
boolean match = list.stream()
.peek(sku -> System.out.println(sku.getSkuName()))
// noneMatch
.noneMatch(sku -> sku.getTotalPrice() > 10_000);
System.out.println(match);
}