Java8之流Stream使用,附上例子
Posted zexzhang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java8之流Stream使用,附上例子相关的知识,希望对你有一定的参考价值。
package stream; import java.util.*; import java.util.concurrent.CopyOnWriteArrayList; import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; public class steamMain { public static void main(String[] args) { /** * map函数 * 将流中的每?个元素 T 映射为 R(类似类型转换) * 上堂课的例?就是,类似遍历集合,对集合的每个对象做处理 * 场景:转换对象,如javaweb开发中集合??的DO对象转换为DTO对象 */ List<String> list = Arrays.asList("springboot教程", "微服务教程", "并发编程", "压?测试", "架构课程"); List<String> li = Arrays.asList("asdad", "dfsfs", "erdsd", "zxcsdad", "weqqweqsd"); List<String> resultlist = list.stream().map(obj -> "我想学习" + obj).collect(Collectors.toList()); System.out.println(resultlist); List<user> list1 = Arrays.asList(new user(12, "123"), new user(23, "234"), new user(24, "345")); List<userDTO> resLIst = list1.stream().map(obj -> { userDTO user = new userDTO(); user.setName(obj.getName()); return user; }).collect(Collectors.toList()); System.out.println(resLIst); /** * filter 函数 * ?于通过设置的条件过滤出元素 * 需求:过滤出字符串?度?于5的字符串 */ List<String> list2 = list.stream().filter(obj -> obj.length() > 4).collect(Collectors.toList()); System.out.println(list2); /** * sorted 函数 * sorted() 对流进??然排序, 其中的元素必须实现Comparable 接? */ //默认升序 //List<String> list4 = li.stream().sorted(Comparator.comparing(String::length)).collect(Collectors.toList()); //反转 降序 //List<String> list4 = li.stream().sorted(Comparator.comparing(String::length).reversed()).collect(Collectors.toList()); List<String> list4 = li.stream().sorted(Comparator.comparing(String::length, Comparator.reverseOrder())).collect(Collectors.toList()); System.out.println(list4); /** * limit函数 * 截断流使其最多只包含指定数量的元素 */ List<String> list5 = li.stream().limit(3).collect(Collectors.toList()); System.out.println(list5); /** * allMatch函数 * 检查是否匹配所有元素,只有全部符合才返回true */ boolean status = li.stream().allMatch(obj -> obj.length() > 4); System.out.println(status); /** * anyMatch函数 * 检查是否?少匹配?个元素 只要又一个符合要求,返回true */ boolean status1 = li.stream().anyMatch(obj -> obj.length() > 10); System.out.println(status1); /** * max函数 */ // Optional<user> list7 = list1.stream().max(Comparator.comparingInt(user::getAge)); Optional<user> list7 = list1.stream().max((s1, s2) -> Integer.compare(s1.getAge(), s2.getAge())); System.out.println(list7.get().getAge()); /** * min函数 */ //Optional<user> list8 =list1.stream().min(Comparator.comparingInt(user::getAge)); Optional<user> list8 = list1.stream().min((s1, s2) -> Integer.compare(s1.getAge(), s2.getAge())); System.out.println(list8.get().getAge()); /** * 并行流 parallelStream * 为什么会有这个并?流 * 集合做重复的操作,如果使?串?执?会相当耗时,因此?般会采?多线程来加快, Java8的 * paralleStream?fork/join框架提供了并发执?能? * 底层原理 * 线程池(ForkJoinPool)维护?个线程队列 * 可以分割任务,将?任务拆分成?任务,完全贴合分治思想 * * paralleStream并?是否?定?Stream串?快? * 错误,数据量少的情况,可能串?更快,ForkJoin会耗性能 * 多数情况下并??串?快,是否可以都?并? * 不?,部分情况会有线程安全问题,parallelStream??使?的外部变量,?如集合? * 定要使?线程安全集合,不然就会引发多线程安全问题 */ //两种区别 System.out.println("Stream输出集合"); li.stream().forEach(System.out::println); System.out.println("parallelStream"); li.parallelStream().forEach(System.out::println); //使用parallelStream有线程安全问题,所以集合对象需要集合安全的对象 //循环10次 for (int i = 0; i < 10; i++) { //arrayList的添加方法没有加锁,线程不安全 //List paralleList = new ArrayList(); List paralleList = new CopyOnWriteArrayList(); //生成0到100的数,并行的加入到数组 IntStream.range(0, 100).parallel().forEach(paralleList::add); //如果是用的是ArrayList 这里会报数组下标越界异常,原因ArrayLits的add方法没有加锁,循环到了第9次时,因为是多线程,查看size的时候,都同时加1了,导致下标越界。 //换成CopyOnWriteArrayList集合则不会,因为CopyOnWriteArrayList集合的add方法有加锁 System.out.println(paralleList.size()); } /** * reduce操作 * 什么是reduce操作 * 聚合操作,中?意思是 “减少” * 根据?定的规则将Stream中的元素进?计算后返回?个唯?的值 * 常??法? Optional<T> reduce(BinaryOperator<T> accumulator); */ //累加器 int value = Stream.of(1, 2, 3, 4, 5, 6).reduce((item1, item2) -> item1 + item2).get(); System.out.println(value); //带起始值的累加器 int value1 = Stream.of(1, 2, 3, 4, 5, 6).reduce(100, (item1, item2) -> item1 + item2); System.out.println(value1); //使用reduce求出最大值 int value2 = Stream.of(213, 2312, 12, 454).reduce((item1, item2) -> item1 > item2 ? item1 : item2).get(); System.out.println(value2); /** * foreach操作 * 集合遍历的?式 * for循环 * 迭代器 Iterator * * Jdk8??的新增接? * default void forEach(Consumer<? super T> action) { * Objects.requireNonNull(action); * for (T t : this) { * action.accept(t); * } * } * * 注意点 * 不能修改包含外部的变量的值 * 不能?break或者return或者continue等关键词结束或者跳过循环 */ list1.stream().forEach(obj -> System.out.println(obj)); int totalAge = 0; //测试修改包含外部的变量的值 // list1.stream().forEach(obj ->{ // System.out.println(obj); // totalAge += obj.getAge(); // }); //测试?break或者return或者continue等关键词结束或者跳过循环 // li.stream().forEach(obj ->{ // System.out.println(obj); // return; // }); /** * collector 收集器 * ?个终端操作, ?于对流中的数据进?归集操作,collect?法接受的参数是?个Collector * 有两个重载?法,在Stream接??? * default void forEach(Consumer<? super T> action) { * Objects.requireNonNull(action); * for (T t : this) { * action.accept(t); * } * } * List<Student> results = Arrays.asList(new Student(32),new * Student(33),new Student(21),new Student(29),new Student(18)); * results.forEach(obj->{ * System.out.println(obj.toString()); * }); * Collector的作? * 就是收集器,也是?个接?, 它的?具类Collectors提供了很多???法 * Collectors 的作? * ?具类,提供了很多常?的收集器实现 * Collectors.toList() * ArrayList::new,创建?个ArrayList作为累加器 * List::add,对流中元素的操作就是直接添加到累加器中 * reduce操作, 对?任务归集结果addAll,后?个?任务的结果直接全部添加到 * 前?个?任务结果中 * CH_ID 是?个unmodifiableSet集合 * Collectors.toMap() * Collectors.toSet() * Collectors.toCollection() :??定义的实现Collection的数据结构收集 * Collectors.toCollection(LinkedList::new) * Collectors.toCollection(CopyOnWriteArrayList::new) * Collectors.toCollection(TreeSet::new) */ List<String> listStr = Stream.of("dsad", "dasdsa", "123dsa").collect(Collectors.toList()); System.out.println(listStr); //set集合 Set<String> setStr = Stream.of("dsad", "dasdsa", "123dsa", "123dsa").collect(Collectors.toSet()); System.out.println(setStr); Set<String> setStr1 = Stream.of("dsad", "dasdsa", "123dsa", "123dsa").collect(Collectors.toCollection(TreeSet::new)); System.out.println(setStr1); List<String> listStr1 = Stream.of("dsad", "dasdsa", "123dsa", "123dsa").collect(Collectors.toCollection(ArrayList::new)); System.out.println(listStr1); /** * join函数 * 拼接函数 Collectors.joining * //重载?法? * <R> R collect(Supplier<R> supplier, BiConsumer<R, ? super T> * accumulator, BiConsumer<R, R>combiner); * //重载?法? * <R, A> R collect(Collector<? super T, A, R> collector); * public static <T> Collector<T, ?, List<T>> toList() { * return new CollectorImpl<>((Supplier<List<T>>) * ArrayList::new, List::add,(left, right) -> { * left.addAll(right); return left; }, CH_ID); * } * 其中?个的实现 * 说明: * 该?法可以将Stream得到?个字符串, joining函数接受三个参数,分别表示 元素之间的连 * 接符、前缀和后缀。 */ //将数组集合"||"拼接在一起 String value3 = list.stream().collect(Collectors.joining("||")); System.out.println(value3); //还可以使用join函数,指定前缀和后缀 String value4 = list.stream().collect(Collectors.joining("||", "{", "}")); System.out.println(value4); /** * partitioningBy分组 * Collectors.partitioningBy 分组,key是boolean类型 * public static <T> * Collector<T, ?, Map<Boolean, List<T>>> partitioningBy(Predicate<? super * T> predicate) { * return partitioningBy(predicate, toList()); * } */ //将数组长度大于5的字符串分出来 Map<Boolean,List<String>> boMap = li.stream().collect(Collectors.partitioningBy(obj -> obj.length() > 5)); boMap.forEach((k,v) ->{ System.out.println(k+"->"+v); }); /** * groupby 分组 * 分组 Collectors.groupingBy() * public static <T, K> Collector<T, ?, Map<K, List<T>>> groupingBy(Function<? * super T, ? extends K> classifier) { return groupingBy(classifier, toList()); * } */ //练习:根据学?所在的省份,进?分组 List<Student> studentList = Arrays.asList(new Student("?东", 23), new Student("?东", 24), new Student("?东", 23),new Student("北京", 22), new Student("北京", 20), new Student("北京", 20),new Student("海南", 25)); Map<String,List<Student>> stuMap = studentList.stream().collect(Collectors.groupingBy(obj -> obj.getProvince())); stuMap.forEach((k,v)->{ System.out.println(k+"有"+v); }); //算出每个地区有多少人 /** * 分组统计,groupby分组进阶 * 分组后进行统计Collectors.counting() 统计元素个数 */ Map<String,Long> longMap = studentList.stream().collect(Collectors.groupingBy(obj -> obj.getProvince(),Collectors.counting())); longMap.forEach((k,v)->{ System.out.println(k+"有"+v+"人"); }); /** * groupby分组进阶 * summarizing集合统计 * 作?:可以?个?法把统计相关的基本上都完成 * 分类 * summarizingInt * summarizingLong * summarizingDouble */ IntSummaryStatistics summaryStatistics = studentList.stream().collect(Collectors.summarizingInt(obj -> obj.getAge())); System.out.println("平均年龄"+summaryStatistics.getAverage()); System.out.println("总人数"+summaryStatistics.getCount()); System.out.println("最大年龄"+summaryStatistics.getMax()); System.out.println("最小年龄"+summaryStatistics.getMin()); } }
package stream; public class Student { private String province; private int age; public Student() { } public Student(String province, int age) { this.province = province; this.age = age; } @Override public String toString() { return "Student{" + "province=‘" + province + ‘‘‘ + ", age=" + age + ‘}‘; } public String getProvince() { return province; } public void setProvince(String province) { this.province = province; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
package stream; public class user { private int age; private String name; public user(int age, String name) { this.age = age; this.name = name; } public user() { } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "user{" + "age=" + age + ", name=‘" + name + ‘‘‘ + ‘}‘; } }
package stream; public class userDTO { private String name; public userDTO(String name) { this.name = name; } public userDTO() { } public String getName() { return name; } public void setName(String name) { this.name = name; } }
以上是关于Java8之流Stream使用,附上例子的主要内容,如果未能解决你的问题,请参考以下文章
java8 stream, map, Option 等函数式编程的使用例子