Java8特性: stream
Posted 唐微港
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java8特性: stream相关的知识,希望对你有一定的参考价值。
串行流
什么是Stream流
java.util.stream中定义的流,其中提供了一些常用的API让我们对数据进行处理。
流API中的流操作的数据源,是数组或者是集合。它本身是不存储数据的,只是移动数据,在移动过程中可能会对数据进行过滤,排序或者其它操作
但是,一般情况下(绝大数情况下),流操作本身不会修改数据源,比如,对流排序不会修改数据源的顺序。相反,它会创建一个新的流,其中包含排序后的结果。
演示实例准备
-
首先创建一个Student类,以后演示每次都使用这个类
public class Student { private Integer id; private String name; private Integer age; private Double score; public Student() { } public Student(Integer id, String name, Integer age, Double score) { this.id = id; this.name = name; this.age = age; this.score = score; } //getter和setter方法 //toString方法 }
-
然后下面再创建一个StudentData类,用于获取其数据
public class StudentData { public static List<Student> getStudents(){ List<Student> list = new ArrayList<>(); list.add(new Student(1,"刘备",18,90.4)); list.add(new Student(2,"张飞",19,87.4)); list.add(new Student(3,"关羽",21,67.4)); list.add(new Student(4,"赵云",15,89.4)); list.add(new Student(5,"马超",16,91.4)); list.add(new Student(6,"曹操",19,83.4)); list.add(new Student(7,"荀彧",24,78.4)); list.add(new Student(8,"孙权",26,79.4)); list.add(new Student(9,"鲁肃",21,93.4)); return list; } }
创建Stream流的几种方式
-
通过一个集合创建Stream
@Test public void test1(){ List<Student> studentList = StudentData.getStudents(); //第一种:返回一个顺序流 Stream<Student> stream = studentList.stream(); //第二种:返回一个并行流 Stream<Student> stream2 = studentList.parallelStream(); }
-
通过一个数组创建Stream
@Test public void test2(){ //获取一个整形Stream int[] arr = new int[]{1,2,34,4,65,7,87,}; IntStream intStream = Arrays.stream(arr); //获取一个Student对象Stream Student[] students = StudentData.getArrStudents(); Stream<Student> stream = Arrays.stream(students); }
-
通过Stream.of
@Test public void test3(){ Stream<Integer> integerStream = Stream.of(1, 2, 3, 5, 6, 7, 8); Stream<String> stringStream = Stream.of("1", "2", "3", "4", "5"); Stream<Student> studentStream = Stream.of( new Student(1, "刘备", 24, 90.4), new Student(2, "张飞", 19, 87.4), new Student(3, "关羽", 21, 67.4)); }
-
创建一个无限流。使用generate方法生成的Stream通常用于随机数和常量
@Test public void test4(){ //每隔5个数取一个,从0开始,此时就会无限循环 Stream.iterate(0,t->t+5).forEach(System.out::println); //每隔5个数取一个,从0开始,只取前5个数 Stream.iterate(0,t->t+5).limit(5).forEach(System.out::println); //取出一个随机数 Stream.generate(Math::random).limit(5).forEach(System.out::println); }
stream操作方法分类
中间聚合操作:map (mapToInt, flatMap 等)、 filter、 distinct、 sorted、 peek、 skip、 parallel、 sequential、 unordered。(过度可以继续连调)
最终输出操作:forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、iterator。(最终方法不能继续连调)
短路操作:anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 limit。
常见Stream的API
-
筛选和切片
@Test public void test1(){ List<Student> list = StudentData.getStudents(); //(1)过滤:过滤出所有年龄大于20岁的同学 list.stream().filter(item->item.getAge()>20).forEach(System.out::println); //(2)截断流:筛选出前3条数据 list.stream().limit(3).forEach(System.out::println); //(3)跳过元素:跳过前5个元素 list.stream().skip(5).forEach(System.out::println); //(4)过滤重复数据: list.stream().distinct().forEach(System.out::println); }
-
映射
将Stream中的元素进行映射转换,比如将“a”转为“A”,期间生产了新的Stream。同时为了提升效率,官方也提供了封装好的方法:mapToDouble,mapToInt,mapToLong。
@Test public void test2(){ //(1)map操作 List<String> list = Arrays.asList("java","python","go"); Stream<String> stream = list.stream(); //此时每一个小写字母都有一个大写的映射 stream.map(str -> str.toUpperCase()).forEach(System.out::println); //筛选出所有的年龄,再过滤出所有大于20的年龄有哪些 List<Student> studentList = StudentData.getStudents(); Stream<Student> stream1 = studentList.stream(); Stream<Integer> ageStream = stream1.map(Student::getAge); ageStream.filter(age->age>20).forEach(System.out::println); //(2)floatMap:将流中的每一个值换成另外一个流 }
-
排序
public void test3(){ //(1)自然排序 List<Integer> list = Arrays.asList(4,3,7,9,12,8,10,23,2); Stream<Integer> stream = list.stream(); stream.sorted().forEach(System.out::println); //(2)对象排序:对象类可以先实现comparable接口,或者是直接指定 //第一种:先实现compable接口 List<Student> studentList = StudentData.getStudents(); studentList.stream().sorted().forEach(System.out::println); //第二种:直接指定comparable List<Student> studentList1 = StudentData.getStudents(); studentList1.stream() .sorted((e1,e2)-> Integer.compare(e1.getAge(),e2.getAge())) .forEach(System.out::println); }
-
匹配和查找(最终)
public void test1(){ List<Student> list = StudentData.getStudents(); //(1)判断所有的学生年龄是否都大于20岁 boolean allMatch = list.stream().allMatch(item -> item.getAge() > 20); //(2)判断是否存在学生的年龄大于20岁 boolean anyMatch = list.stream().anyMatch(item -> item.getAge() > 20); //(3)判断是否存在学生叫曹操 boolean noneMatch = list.stream().noneMatch(item -> item.getName().equals("曹操")); //(4)查找第一个学生 Optional<Student> first = list.stream().findFirst(); //(5)查找所有的学生数量 long count = list.stream().count(); long count1 = list.stream().filter(item -> item.getScore() > 90.0).count(); //(6)查找当前流中的元素 Optional<Student> any = list.stream().findAny(); //(7)查找学生最高的分数:Student实现了comparable接口的话,可直接比较 Stream<Double> doubleStream = list.stream().map(item -> item.getScore()); doubleStream.max(Double::compare); //(8)查找学生最低的分数 }
-
归约(最终)
public void test2(){ //(1)计算数的总和 List<Integer> list = Arrays.asList(1,2,3,4,5); list.stream().reduce(0,Integer::sum); //(3)计算学生总分 List<Student> studentList = StudentData.getStudents(); Stream<Double> doubleStream = studentList.stream().map(Student::getScore); doubleStream.reduce(Double::sum); }
-
收集(最终)
public void test3(){ List<Student> studentList = StudentData.getStudents(); //返回一个list List<Student> listStream = studentList.stream() .filter(e -> e.getAge() > 18) .collect(Collectors.toList()); //返回一个Set Set<Student> setStream = studentList.stream() .filter(e -> e.getAge() > 18) .collect(Collectors.toSet()); //返回其他的类型 }
并行流
并行流的处理方法和Stream相同知识将stream变成了parallelStream();
参考学习
https://blog.csdn.net/wo541075754/article/details/102458705
https://blog.csdn.net/sdddlll/article/details/103551347
https://www.cnblogs.com/zhenghengbin/p/9500822.html
https://www.jianshu.com/p/ac2bcf2f9d48
以上是关于Java8特性: stream的主要内容,如果未能解决你的问题,请参考以下文章