1.集合流的简介
1.1集合的流式编程简介
Stream是JDK1.8之后出来的新特性,也是JDK1.8中最值得学习的两种新特性之一。(另外一个是lambda表达式)
Stream是对集合操作的增强,流不是集合元素,不是一种数据结构,不负责数据的存储。流更像是一种迭代器,可以单向的遍历一个集合中的每一个元素,并且不可循环。
1.2 为什么要使用集合的流式编程
集合的流式编程可以大幅度简化代码数量,将数据源中的数据读取到一个流中,可以对流中的数据进行删除、过滤、映射等多种操作,每次操作返回的结果也是一个流对象,可以对这个流对象再次进行操作
1.3 使用流式编程的步骤
通常情况,对集合中的数据使用流式编程需要以下三个步骤
- 1、获取数据源,将数据源中的数据读取到流中
- 2、对流中的数据进行各种处理
- 3、对流中的数据整合处理
上述过程中,过程2中,可以有若干方法对流中的数据进行各种操作,并且返回流对象本身,这种操作,被称为中间操作。过程3中,有若干方法,可以对流中的数据进行各种处理,并且关闭流,这种操作,被称为最终操作
2.数据源的获取
2.1数据源的简介
数据源是流中的数据来源,是集合流式编程的第一步,将数据源中的数据读取到流中,进行处理。==注意:将数据读取到流中进行处理的时候,与数据源中的数据没有关系。就是说,中间操作对对流中的数据进行处理、过滤、映射、排序等,此时都不会影响数据源中的数据==
2.2数据源的获取
将集合容器中的数据读取到一个流中,无论什么容器作为数据源,读取到流中返回的都是一个Stream
1 2 3 4 5 6
| Stream<Integer> stream = list.stream();
Stream<Integer> stream = list.parallelStream();
IntStream stream = Arrays.stream(array).collect(Collectors.toMap(e1 -> e1, o -> o * 10))
|
stream()和parallelStream的区别
stream()方法获取的数据源是串行的,parallelStream()获取的数据源是并行的。parallelStream()内部集成了多个线程对流中的数据进行操作,效率更高。
3.最终操作
3.1最终操作简介
将流中的数据整合到一起,存入一个集合,也可以直接对流中的数据进行遍历、数据统计等等,通过最终操作,需要掌握如何从流中提取我们想要的信息。
注意事项:之所以叫最终操作,是因为,在最终操作执行结束后,会关闭这个流,流中所有数据都会销毁。如果使用一个已经关闭了的流,会出现异常
3.2 collect
将流中的数据收集到一起,对数据进行处理。最常见的处理是将流中的数据存入一个集合,collect方法的参数是一个Collector接口,而且不是一个函数式接口,实现这个接口,可以自定义收集规则。绝大部分情况,不需要自定义规则,直接使用Collectors工具类提供的方法即可。
1 2 3 4 5 6 7
| List<Integer> result = list.stream().collect(Collectors.toList);
Set<Integer> result1 = list.stream().collect(Collectors.toSet);
Map<Integer,Integer> result2 = list.stream().collect(Collectors.toMap(o1 -> o1, o2 -> o2*10))
|
3.3 reduce
将流中的数据按照一定的规则聚合起来
1 2 3
|
int result = list.stream().reduce(o1,o2->o1+o2).get();
|
3.4 count
统计流中元素的数量
1
| int result = list.stream().count();
|
3.5 foreach
迭代,遍历
1
| integerList.stream().forEach(System.out::println);
|
3.6 max & min
获取流中最大或者最小的元素
1
| integerList.stream().max(Integer::compareTo).get();
|
3.7 Matching
1 2 3 4 5 6 7 8 9
| boolean b = integerList.stream().allMatch(integer -> integer >= 1);
boolean b1 = integerList.stream().anyMatch(integer -> integer >= 4);
boolean b2 = integerList.stream().noneMatch(integer -> integer >= 4); System.out.println(b); System.out.println(b1); System.out.println(b2);
|
3.8 find
1 2 3 4 5 6 7 8 9 10
| List<Integer> integerList = new ArrayList<>(); Collections.addAll(integerList, 1, 2, 3);
Integer integer = integerList.stream().findFirst().get();
Integer integer2 = integerList.stream().findAny().get(); Integer integer3 = integerList.parallelStream().findAny().get(); System.out.println(integer); System.out.println(integer2); System.out.println(integer3);
|
3.9 最终操作注意事项
最终操作会关闭流,如果操作一个已经关闭了的流会报异常
1 2 3 4 5 6 7 8 9
| List<Integer> integerList = new ArrayList<>(); Collections.addAll(integerList, 1, 2, 3); Stream<Integer> stream = integerList.stream(); long count = stream.count(); System.out.println(count); Integer integer = stream.max(Integer::compareTo).get(); System.out.println(integer);
|
4.0 InStream等基本数据类型的最终操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| int[] ints = new int[]{1, 2, 3, 4, 5}; IntStream intStream = Arrays.stream(ints);
IntSummaryStatistics intSummaryStatistics = intStream.summaryStatistics(); System.out.println(intSummaryStatistics.getMax()); System.out.println(intSummaryStatistics.getMin()); System.out.println(intSummaryStatistics.getSum()); System.out.println(intSummaryStatistics.getCount()); System.out.println(intSummaryStatistics.getAverage());
|
4. 中间操作
对流中的数据进行各种操作、处理。中间操作可以是连续操作,每一次操作返回的都是一个Stream对象,可以继续进行其它操作,直到最终操作
4.1 filter
条件过滤,仅保留满足条件的数据,其它不满足条件的数据会被删除
1 2 3
| List<Integer> integerList = new ArrayList<>(); Collections.addAll(integerList, 1, 2, 3, 4, 5, 6); integerList.stream().filter(integer -> integer > 5).forEach(System.out::println);
|
4.2 distinct
去除集合中重复的元素,方法没有参数。去重规则和hashSet相同
1 2 3 4 5 6 7 8
| List<Student> students = new ArrayList<>(); Collections.addAll(students, new Student("zhangsan",16,90), new Student("lisi",18,70), new Student("zhaowu",17,98), new Student("zhaowu",17,98) ); students.stream().distinct().forEach(System.out::println);
|
4.3 sorted
将流中的元素进行排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| public static void sortedDataSource() { List<Student> students = new ArrayList<>(); Collections.addAll(students, new Student("zhangsan", 16, 90), new Student("lisi", 18, 70), new Student("zhaowu", 17, 98), new Student("zhaowu", 17, 98) );
students.stream().distinct().sorted((o1, o2) -> o1.score - o2.score).forEach(System.out::println); }
@Data static class Student implements Comparable<Student> { private String name; private int age; private int score;
public Student(String name, int age, int score) { this.name = name; this.age = age; this.score = score; }
@Override public int compareTo(Student o) { return this.age - o.age; } }
|
4.4 limit & skip
limit: 限制,截取流中指定数量的元素
skip: 跳过,跳过流中指定数量的元素
1 2 3 4 5 6
| list.stream().limit(2).forEach(System.out::println);
list.stream().skip(2).forEach(System.out::println);
list.stream().skip(2).limit(1).forEach(System.out::println);
|
4.5 map & flatMap
map: 对流中的数据进行映射,用新数据替换旧的数据
1 2
| Stream<String> stream = students.stream().map(student -> String.valueOf(student.getAge()) + "岁"); System.out.println("stream.collect(Collectors.toList()) = " + stream.collect(Collectors.toList()));
|
flatMap是扁平化映射
1 2
| students.stream().map(student -> student.getName().split("")).flatMap(Arrays::stream).distinct().forEach(System.out::println);
|
4.6 mapToInt,mapToLong等
将流中的数据替换成Int类型,得到IntStream等对象,可以进行统计操作
1 2
| IntStream intStream = students.stream().mapToInt(Student::getAge); System.out.println("intStream.summaryStatistics().getAverage() = " + intStream.summaryStatistics().getAverage());
|
5. Collectors工具类
方法 |
描述 |
Collectors.toList() |
将流中的数据聚合到一个List中 |
Collectors.toSet() |
将流中的数据聚合到一个Set中 |
Collectors.toMap() |
将流中的数据聚合到一个Map中 |
maxBy() |
按照指定规则,找到流中最大元素,等同于max |
minBy() |
按照指定规则,找到流中最小元素,等同于min |
joining() |
将流中的数据拼接成一个字符串,注意:只能操作流中String的数据 |
summingInt() |
将流中的数据,映射成int类型数据,并求和 |
averagingInt() |
将流中的数据,映射成int类型数据,并求平均值 |
summarizingInt() |
将流中的数据,映射成int类型数据,并获取描述信息 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| Student student = students.stream().collect(Collectors.maxBy((o1, o2) -> o1.getAge() - o2.getAge())).get(); System.out.println(student);
String collect = students.stream().map(Student::getName).collect(Collectors.joining()); System.out.println(collect);
Integer collect1 = students.stream().collect(Collectors.summingInt(Student::getAge)); System.out.println(collect1);
Double collect2 = students.stream().collect(Collectors.averagingInt(Student::getAge)); System.out.println(collect2);
IntSummaryStatistics collect3 = students.stream().collect(Collectors.summarizingInt(Student::getAge)); System.out.println(collect3.getMax());
|