Java8Stream中间操作使用详解
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Java8Stream中间操作使⽤详解
前⾯两篇简单的介绍了Stream以及如何创建Stream,本篇就给⼤家说说stream有哪些⽤途,以及具体怎样使⽤。
再次介绍Stream
Stream 使⽤⼀种类似⽤于SQL 语句从数据库查询数据的直观⽅式来提供⼀种对 Java 集合运算和表达的⾼阶抽象。
Stream API可以极⼤提⾼Java程序员的⽣产⼒,让程序员写出⾼效率、⼲净、简洁的代码。
这种风格将要处理的元素集合看作⼀种流,流在管道中传输,并且可以在管道的节点上进⾏处理,⽐如筛选,排序,聚合等。
Stream两种操作
中间操作(Intermediate Operations):中间操作会返回⼀个新的流,⼀个流可以后⾯跟随零个或多个intermediate操作。
其⽬的主要是打开流,做出某种程度的数据映射/过滤,然后会返回⼀个新的流,交给下⼀个操作使⽤。
这类操作都是惰性化的(lazy),就是说,仅仅调⽤到这类⽅法,并没有真正开始流的遍历。
⽽是在终端操作开始的时候才真正开始执⾏。
终端操作(Terminal Operations):是指返回最终的结果。
⼀个流只能有⼀个terminal操作,当这个操作执⾏后,流就被使⽤“光”了,⽆法再被操作。
所以这必定是流的最后⼀个操作。
Terminal操作的执⾏,才会真正开始流的遍历,并且会⽣成⼀个结果,或者⼀个side effect。
中间操作⽅法分类:
filter()
map()
flatMap()
distinct()
sorted()
peek()
limit()
skip()
终端操作⽅法分类:
forEach()
forEachOrdered()
toArray()
reduce()
collect()
min()
max()
count()
anyMatch()
allMatch()
noneMatch()
findFirst()
findAny()
中间操作代码实例详解
1、filter(): 返回结果⽣成新的流中只包含满⾜筛选条件的数据。
// 1、filter,返回⼤于2的元素集合
List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> result = nums.stream().filter(n -> n > 2).collect(Collectors.toList());
System.out.println(result);
运⾏结果:[3, 4, 5]
2、map():将流中的元素进⾏再次加⼯形成⼀个新流,流中的每⼀个元素映射为另外的元素。
// 2、map:返回元素的⼤写类型和哈希值
List<String> mzc = Arrays.asList("ma", "zhi", "chu");
List<String> mzcUpperCase = mzc.stream().
map(n -> n.toUpperCase()).
collect(Collectors.toList());
List<Integer> mzcHashCode = mzc.stream().map(n -> n.hashCode()).collect(Collectors.toList());
System.out.println("mzcUpperCase:"+mzcUpperCase+" ----- mzcHashCode:"+mzcHashCode);
运⾏结果:
mzcUpperCase:[MA, ZHI, CHU] ----- mzcHashCode:[3476, 120571, 98480]
⽰例场景:取出商品的所有id,就可以这样写(伪代码):
List<Product> productList = productService.selectAll();
List<Integer> pIds = productList.stream().map(p->p.getId).collect(Collectors.toList());
这样就可以拿到所有商品id的集合。
3、flatMap():扁平化映射,它具体的操作是将多个stream连接成⼀个stream,这个操作是针对类似多维数组的,⽐如集合⾥⾯包含集合,相当于降维作⽤。
flatMap是将流中的每个元素都放到⼀个流中,最后将所有的流合并成⼀个新流,所有流对象中的元素都合并到这个新⽣成的流中返回。
// flatMap:将多层集合中的元素取出来,放到⼀个新的集合中去
List<Integer> num1 = Arrays.asList(1, 2, 3);
List<Integer> num2 = Arrays.asList(4, 5, 6);
List<Integer> num3 = Arrays.asList(7, 8, 9);
List<List<Integer>> lists = Arrays.asList(num1, num2, num3);
Stream<Integer> outputStream = lists.stream().flatMap(l -> l.stream());
List<Integer> flatMapResult = outputStream.sorted().collect(Collectors.toList());
System.out.println(flatMapResult);
运⾏结果:[1, 2, 3, 4, 5, 6, 7, 8, 9]
⽰例场景:取出所有部门⼈员的姓名,就可以这样写(伪代码):
// 1、取出所有部门
List<Department> departments = ...;
// 2、这个时候可以利⽤flatMap先将所有部门的所有⼈员汇聚起来
List<Person> persons = departments.stream.flatMap(d->d.getPersonList()).collect(Collectors.toList());
// 3、再利⽤map()⽅法取出
4、distinct():顾名思义,将流中的元素去重之后输出。
List<String> mzc = Stream.of("ma","zhi","chu","zhi","shuo","ma")
.distinct()
.collect(Collectors.toList());
System.out.println(mzc);
运⾏结果:[ma, zhi, chu, shuo]
5、sorted():这个很简单了,顾名思义,将流中的元素按照⾃然排序⽅式进⾏排序。
// sorted:⾃然顺序排序
List<Integer> nums = Arrays.asList(1, 3, 5, 6, 8, 2);
List<Integer> sortedNum = nums.stream().sorted().collect(Collectors.toList());
System.out.println(sortedNum);
// sorted:降序排序
List<Integer> sortedNum2 = nums.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
System.out.println(sortedNum2);
// sorted:使⽤Comparator
List<Integer> sortedNums3 = nums.stream().sorted(paring(n -> n)).collect(Collectors.toList());
System.out.println(sortedNums3);
// 不⽤stream直接顺序排序
nums.sort(paring(Integer::intValue));
System.out.println(nums);
//不⽤stream直接降序排序
nums.sort(paring(Integer::intValue).reversed());
[1, 2, 3, 5, 6, 8]
[8, 6, 5, 3, 2, 1]
[1, 2, 3, 5, 6, 8]
[1, 2, 3, 5, 6, 8]
[8, 6, 5, 3, 2, 1]
6、peek():对流中每个元素执⾏操作,并返回⼀个新的流,返回的流还是包含原来流中的元素。
// peek():
String[] arr = new String[]{"a","b","c","d"};
Arrays.stream(arr)
.peek(System.out::println) //a,b,c,d
.count();
// peek()+filter()
Stream.of("ma", "zhi", "chu")
.filter(e -> e.length() > 2)
.peek(e -> System.out.println(e))
.collect(Collectors.toList());
运⾏结果:
a
b
c
d
zhi
chu
7、limit():顾名思义,返回指定数量的元素的流。
返回的是Stream⾥前⾯的n个元素。
// limit():取出100中的前⼗个
List<Integer> limitNum = IntStream.range(1,100).limit(10)
.boxed()
.collect(Collectors.toList());
System.out.println(limitNum);
// limit():取出前4个单词
List<String> words = Arrays.asList("ma", "zhi", "chu", "wait", "you", "follow");
List<String> limitWord = words.stream().limit(4).collect(Collectors.toList());
System.out.println(limitWord);
运⾏结果:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[ma, zhi, chu, wait]
8、skip():和limit()相反,将前⼏个元素跳过(取出)再返回⼀个流,如果流中的元素⼩于或者等于n,就会返回⼀个空的流。
// skip():跳过前⾯三个单词再返回
List<String> words = Arrays.asList("ma", "zhi", "chu", "wait", "you", "follow");
List<String> skipWord = words.stream().limit(4).collect(Collectors.toList());
System.out.println(skipWord);
// skip():跳过全部单词再返回
List<String> emptyWord = words.stream().skip(6).collect(Collectors.toList());
System.out.println(emptyWord);
// skip():跳过超过单词长度的数⽬再返回
List<String> emptyWord2 = words.stream().skip(10).collect(Collectors.toList());
[91, 92, 93, 94, 95, 96, 97, 98, 99]
[ma, zhi, chu, wait]
[]
[]
上⾯讲了Stream流中间操作的使⽤详解,希望能给⼤家带来帮助,如果有⽤,还⿇烦点个在看,或者分享给需要的⼩伙伴,独乐乐不如众乐乐,谢谢!
因为考虑篇幅太长,⼤家看起来可能会有点累,所以Stream的终端操作使⽤详解,串⾏化、并⾏化区别,以及stream流总结放到后⾯的⽂章中。
如果你还想了解更多其他⽅⾯的知识,欢迎留⾔⿎励,我会争取越写越好,越写越全⾯。