结果如图,并行流和串行流时间上错了4倍。
举例: 打印出列表中出来第一个长度为5的单词.. 同时将长度5打印出来. public static void main(String[] args) { List<String> list = Arrays.asList("hello", "world", "hello world"); // list.stream().mapToInt(item -> item.length()).filter(length -> length ==5) // .findFirst().ifPresent(System.out::println); list.stream().mapToInt(item -> { int length = item.length(); System.out.println(item); return length; }).filter(length -> length == 5).findFirst().ifPresent(System.out::println); //返回的是hello , 不包含 world. }返回的是hello , 不包含 world.
流的操作原理: 把流想成一个容器,里边存储的是对每一个元素的操作。操作时,把操作串行化。对同一个元素进行串行的操作。操作中还包含着短路操作。
举例: 找出 这个集合中所有的单词,而且要去重. flatMap()的使用。 public static void main(String[] args) { //举例; 找出 这个集合中所有的单词,而且要去重. List<String> list = Arrays.asList("hello welcome", "world hello", "hello world", "hello hello world"); // list.stream().map(item -> item.split(" ")).distinct() // .collect(Collectors.toList()).forEach(System.out::println); //使用map不能满足需求, 使用flatMap list.stream().map(item -> item.split(" ")).flatMap(Arrays::stream) .distinct().collect(Collectors.toList()).forEach(System.out::println); //结果为 hello welcome world } 举例:组合起来. 打印出 hi zhangsan , hi lisi , hi wangwu , hello zhangsan , hello lisi .... flatMap()的使用。 public static void main(String[] args) { //组合起来. 打印出 hi zhangsan , hi lisi , hi wangwu , hello zhangsan , hello lisi .... List<String> list = Arrays.asList("Hi", "Hello", "你好"); List<String> list1 = Arrays.asList("zhangsan", "lisi", "wangwu"); List<String> collect = list.stream().flatMap(item -> list1.stream().map(item2 -> item + " " + item2)).collect(Collectors.toList()); collect.forEach(System.out::println); } 举例: 流对分组/分区操作的支持. group by / protition by public static void main(String[] args) { //数据准备. Student student1 = new Student("zhangsan", 100, 20); Student student2 = new Student("lisi", 90, 20); Student student3 = new Student("wangwu", 90, 30); Student student4 = new Student("zhangsan", 80, 40); List<Student> students = Arrays.asList(student1, student2, student3, student4); //对学生按照姓名分组. Map<String, List<Student>> listMap = students.stream().collect(Collectors.groupingBy(Student::getName)); System.out.println(listMap); //对学生按照分数分组. Map<Integer, List<Student>> collect = students.stream().collect(Collectors.groupingBy(Student::getScore)); System.out.println(collect); //按照年龄分组. Map<Integer, List<Student>> ageMap = students.stream().collect(Collectors.groupingBy(Student::getAge)); System.out.println(ageMap); //按照名字分组后,获取到每个分组的元素的个数. Map<String, Long> nameCount = students.stream().collect(Collectors.groupingBy(Student::getName, Collectors.counting())); System.out.println(nameCount); //按照名字分组,求得每个组的平均值. Map<String, Double> doubleMap = students.stream().collect(Collectors.groupingBy(Student::getName, Collectors.averagingDouble(Student::getScore))); System.out.println(doubleMap); //分区, 分组的一种特例. 只能分两个组 true or flase . partitioning By Map<Boolean, List<Student>> collect1 = students.stream().collect(Collectors.partitioningBy(student -> student.getScore() >= 90)); System.out.println(collect1); } Java8(3)Collector类源码分析继续学习Java8 新特性。
Collector类源码分析2020了你还不会Java8新特性?jdk8是怎么对底层完成支持的。不了解底层,平时用还可以,但是遇到问题的时候就会卡在那里。迟迟灭有解决方案。在学习一门新技术时,先学习怎么去用,不要执着于源码。但是随着用的越来越多,你去了解底层是比较好的一种学习方法。
有多种方法可以实现同一个功能.什么方式更好呢? 越具体的方法越好. 减少自动装箱拆箱操作collect : 收集器
Collector作为collect方法的参数。
Collector作为一个接口。它是一个可变的汇聚操作,将输入元素累计到一个可变的结果容器中;它会在所有元素都处理完毕后将累计的结果作为一个最终的表示(这是一个可选操作);它支持串行与并行两种方式执行。(并不是说并行一定比串行快。)
Collects本身提供了关于Collectoe的常见汇聚实现,Collectors本身实际上是一个工厂。
为了确保串行和并行的结果一致,需要进行额外的处理。必须要满足两个约束。
identity 同一性
associativity 结合性