1.简介

Stream流 最全的用法
Stream 能用来干什么?用来解决汇合,通过 应用Stream API 对汇合数据进行操作,就相似于应用 SQL 执行的数据库查问,Stream API 提供了一种高效且易于应用的解决数据的形式

为什么用Java 8 Stream ?因为 操作简略
为什么操作简略?因为 Lambda 表达式,它极大的进步了编程效率和程序可读性
怎么操作流? 首先你的有个数据源(数组、汇合),操作会产生新的流对象,原来的流对象不会扭转
流用法有完结操作,这种代码不是你写了一个办法就执行一个办法,而是最初触发完结操作的时候才对立执行的,collect、foreach 办法就是一种完结办法,详情看代码及后果参考 2.映射map、flatMap用法 局部

2.具体用法

2.1 创立流

 // 汇合创立流        List<String> list = new ArrayList<>();        // 获取一个程序流        Stream<String> listStream = list.stream();        // 获取一个并行流        Stream<String> parallelListStream = list.parallelStream();        // 数组创立流        Integer[] nums = new Integer[] { 1, 2, 3, 4, 5 };        Stream<Integer> arrStream = Arrays.stream(nums);        arrStream.forEach(System.out::println);// 1 2 3 4 5        // 静态方法of创立流        Stream<Integer> ofStream = Stream.of(1, 2, 3, 4, 5);        ofStream.forEach(System.out::println);// 1 2 3 4 5        // 静态方法iterate 创立流        Stream<Integer> iterateStream = Stream.iterate(1, (x) -> x + 10).limit(4);        iterateStream.forEach(System.out::println); // 1 11 21 31        // 静态方法generate 创立流        Stream<Double> generateStream = Stream.generate(Math::random).limit(2);        generateStream.forEach(System.out::println);

2.2 操作流

1.过滤

filter:过滤流中的某些元素(能够做一些根本的判空、替换、判断逻辑操作)
limit(n):获取n个元素,后果获取几个元素
skip(n):跳过n元素,配合limit(n)可实现分页
distinct:通过流中元素的 hashCode() 和 equals() 去除反复元素

     //filter 判空     Stream<Integer> notNullStreamObj = Stream.of(1, 2, null, 4, 5, 6, 7, null, 2);     Stream<Integer> notNullStream = notNullStreamObj.filter(i -> (null != i));     notNullStream.forEach(System.out::println);//1 2 4 5 6 7 2     //filter 逻辑判断     Stream<Integer> logicStreamObj = Stream.of(1, 2, null, 4, 5, 6, 7, null, 2);     Stream<Integer> logicStream = logicStreamObj.filter(i -> (i != null && i > 5));     logicStream.forEach(System.out::println); // 6 7     //filter 替换     Stream<String> strStreamObj = Stream.of("aa", "ab", null, "ac", "bd", "ee");     Stream<String> strStream = strStreamObj.filter(str -> (null != str && str.contains("a")));     strStream.forEach(System.out::println); // aa ab ac     //skip 跳过     Stream<String> skipStreamObj = Stream.of("aa", "ab", null, "ac", "bd", "ee");     Stream<String> skipStream = skipStreamObj.skip(2);     skipStream.forEach(System.out::println); // null ac bd ee     //distinct 去重     Stream<String> disStreamObj = Stream.of("aa", "ab", null, "ac", "aa", "ab", null, "ee");     Stream<String> disStream = disStreamObj.distinct();     disStream.forEach(System.out::println); // aa ab null ac ee

2.映射

map:接管一个函数作为参数,该函数会被利用到每个元素上,映射成一个新的元素。
flatMap:接管一个函数作为参数,将流中的每个值都换成另一个流,而后把所有流连接成一个流。
peek:这个操作很骚,相似map只不过map 是Func函数,提供返回值,而peer是取出元素,Consumer表达式设值,我集体感觉没啥区别呢,官网文档提醒:该办法次要用于调试,做一些耗费这个对象但不批改它的货色,没啥事不要用
很想问一下 这俩map、flatMap 区别 ,细品,你细品,你细细品
map是将每个元素 映射成一个新元素,除非你过滤了,否则不会扭转元素个数
flatMap是将原流中的每个值都变成另一个流,而后把流合并串起来,必须有返回值,拼装成新的流

     //map 把蕴含a的元素,替换成| 留神,留神, 元素还是一个整体,对每个元素     Stream<String> mapStreamObj = Stream.of("a,b,c", "a,e,f", "g,h,i");     Stream<String> mapStream = mapStreamObj.map(str -> str.replaceAll(",", "|"));     mapStream.forEach(System.out::println); // a|b|c a|e|f h|i|j     //flatMap 能够把元素 切分后,再依照新元素组成新的字符串     Stream<String> flatMapStreamObj = Stream.of("a,b,c", "a,e,f", "g,h,i");     Stream<String> flatMapStream = flatMapStreamObj.flatMap(str -> {         String[] arr = str.split(",");         Stream<String> result = Arrays.stream(arr);         return result;     });     flatMapStream.forEach(System.out::println); //a b c d e f g h i     System.out.println("1===========");     Stream<String> peekStreamObj = Stream.of("a,b,c", "a,e,f", "g,h,i");     Stream<String> peekStream = peekStreamObj.peek(e -> System.out.println("Filtered value: " + e))             .map(String::toUpperCase)             .peek(e -> System.out.println("Mapped value: " + e));     System.out.println("2=========== peek代码完结,然而日志没打印");     Set<String> stringSet = peekStream.collect(Collectors.toSet());     System.out.println("3=========== collect完结操作,代码日志打印");     stringSet.forEach(System.out::println);

map执行后果

//看下执行后果,阐明 collect才是完结操作,代码完结,然而并不是真正完结1===========2=========== peek代码完结,然而日志没打印Filtered value: a,b,cMapped value: A,B,CFiltered value: a,e,fMapped value: A,E,FFiltered value: g,h,iMapped value: G,H,I3=========== collect完结操作,代码日志打印A,B,CA,E,FG,H,I

3.排序

sorted():天然排序,流中元素需实现Comparable接口
sorted(Comparator com):定制排序,自定义Comparator排序器
先构建一个User类

 public static class User {       private String name;       private Integer age;       public User(String name, Integer age) {           this.name = name;           this.age = age;       }       public String getName() {           return name;       }       public void setName(String name) {           this.name = name;       }       public Integer getAge() {           return age;       }       public void setAge(Integer age) {           this.age = age;       }       @Override       public String toString() {           return "User{" +                   "name='" + name + '\'' +                   ", age=" + age +                   '}';       }   }

而后 看下sort用法

//按字母排序       Stream<String> sortStreamObj = Stream.of("a,e,f", "a,d,c", "a,b,i");       Stream<String> sortStream = sortStreamObj.sorted();       sortStream.forEach(System.out::println); //abi adc aef       User u1 = new User("bb", 1);       User u2 = new User("aa", 2);       User u3 = new User("cc", 3);       User u4 = new User("aa", 4);       Set<User> userSet = Sets.newHashSet(u1, u2, u3, u4);       Stream<User> userStream = userSet.stream().sorted(               (obj1, obj2) -> {                   if (obj1.getName().equals(obj2.getName())) {                       //name相等 按age                       return obj1.getAge() - obj2.getAge();                   }                   return obj1.getName().compareTo(obj2.getName());               }       );       userStream.forEach(System.out::println);// u2 u4 u1 u3

sort 执行后果

a,b,ia,d,ca,e,fUser{name='aa', age=2}User{name='aa', age=4}User{name='bb', age=1}User{name='cc', age=3}

4.流匹配

allMatch:接管一个 Predicate 函数,当流中每个元素都合乎该断言时才返回true,否则返回false
noneMatch:接管一个 Predicate 函数,当流中每个元素都不合乎该断言时才返回true,否则返回false
anyMatch:接管一个 Predicate 函数,只有流中有一个元素满足该断言则返回true,否则返回false
findFirst:返回流中第一个元素
findAny:返回流中的任意元素
count:返回流中元素的总个数
max:返回流中元素最大值
min:返回流中元素最小值

        List<Integer> numLists = Arrays.asList(3, 4, 5, 6, 10);        // 全副匹配 - true        boolean allMatch1 = numLists.stream().allMatch(e -> e > 2); //true        System.out.println("allMatch1:" + allMatch1);        // 全副匹配 - true        boolean allMatch2 = numLists.stream().allMatch(e -> e > 5); //false        System.out.println("allMatch2:" + allMatch2);        // 全副都不合乎 - true        boolean noneMatch = numLists.stream().noneMatch(e -> e > 20); //true        System.out.println("noneMatch:" + noneMatch);        // 任一元素合乎 - true        boolean anyMatch = numLists.stream().anyMatch(e -> e > 4);  //true        System.out.println("anyMatch:" + anyMatch);        //返回第一个        Integer findFirst = numLists.stream().findFirst().get(); //3        System.out.println("findFirst:" + findFirst);        //返回任一个        Integer findAny = numLists.stream().findAny().get();         System.out.println("findAny:" + findAny);        //返回 count        long count = numLists.stream().count(); //5        System.out.println("count:" + count);        //返回max        Integer max = numLists.stream().max(Integer::compareTo).get(); //10        System.out.println("max:" + max);        //返回min        Integer min = numLists.stream().min(Integer::compareTo).get();//3        System.out.println("min:" + min);

匹配执行后果

allMatch1:trueallMatch2:falsenoneMatch:trueanyMatch:truefindFirst:3findAny:3count:5max:10min:3

5.组合操作

Reduce 就是组合操作
Reduce(BinaryOperator accumulator) 没有起始值,依照运算规定进行运算操作
解释:第一次执行时,accumulator函数的第一个参数为流中的第一个元素,第二个参数为流中元素的第二个元素,依照函数进行操作;
第二次执行时,第一个参数为第一次函数执行操作的后果,第二个参数为流中的第三个元素;往下顺次类推,返回Optinal 通过get()办法获取后果
Reduce(T identity, BinaryOperator accumulator)含有初始值,第二个是第一个的变形,跟第一个办法比照,不同的是此次这个会承受一个identity参数,用来指定Stream循环的初始值。如果Stream为空,就间接返回该值,非凡:该办法不会返回 Optional

Optional sumResult = Stream.of(1, 2, 3, 4)                .reduce((sum, item) -> {                    System.out.println("sum : " + sum);                    sum += item;                    System.out.println("item: " + item);                    System.out.println("sum+ : " + sum);                    System.out.println("-----——---");                    return sum;                });        System.out.println("========sumResult: " + sumResult.get());        Integer sumDefineResult = Stream.of(1, 2, 3, 4)                .reduce(100, (sum, item) -> {                    System.out.println("sum : " + sum);                    sum += item;                    System.out.println("item: " + item);                    System.out.println("sum+ : " + sum);                    System.out.println("---——-----");                    return sum;                });        System.out.println("========sumDefineResult: " + sumDefineResult);

reduce 执行后果

//上面是执行后果//查看执行后果sum : 1item: 2sum+ : 3-----——---sum : 3item: 3sum+ : 6-----——---sum : 6item: 4sum+ : 10-----——---========sumResult: 10sum : 100item: 1sum+ : 101---——-----sum : 101item: 2sum+ : 103---——-----sum : 103item: 3sum+ : 106---——-----sum : 106item: 4sum+ : 110---——-----========sumDefineResult: 110

6. 收集转换操作

这是个最最最最最根本的操作,10个流操作 9个都会应用到以后操作

collect(Collectors.toList()) 转换List
collect(Collectors.toSet()) 转换Set
Collectors.toMap(key, value) 转换Map ,如果key反复,!!!报错
Collectors.joining() join进行拼接
Collectors.groupingBy(key) 以Key为map的 key分组
Collectors.partitioningBy(规定) 以规定分区 比方 >5 ,map key为true,false

        User s1 = new User("aa", 1);        User s2 = new User("bb", 2);        User s3 = new User("cc", 3);        User s4 = new User("dd", 2);        List<User> list = Arrays.asList(s1, s2, s3, s4);        //转换list        List<Integer> ageList = list.stream().map(User::getAge).collect(Collectors.toList()); // [1, 2, 3]        System.out.println(ageList.toString());        //转成set        Set<Integer> ageSet = list.stream().map(User::getAge).collect(Collectors.toSet()); // [1, 2, 3]        System.out.println(ageSet);        //转成map,注:key不能雷同,否则报错        Map<String, Integer> userMap = list.stream().collect(Collectors.toMap(User::getName, User::getAge)); // {cc=10, bb=20, aa=10}        System.out.println(userMap);        //字符串分隔符连贯        String joinName = list.stream().map(User::getName).collect(Collectors.joining(",", "(", ")")); // (aa,bb,cc)        System.out.println(joinName);        //分组        Map<Integer, List<User>> ageMap = list.stream().collect(Collectors.groupingBy(User::getAge));        System.out.println(ageMap);        //多重分组,先依据类型分再依据年龄分        Map<Integer, Map<Integer, List<User>>> typeAgeMap = list.stream().collect(Collectors.groupingBy(User::getAge, Collectors.groupingBy(User::getAge)));        System.out.println(typeAgeMap);        //分区        //分成两局部,true 一部分age大于2岁, false 一部分age小于等于2岁        Map<Boolean, List<User>> partMap = list.stream().collect(Collectors.partitioningBy(v -> v.getAge() > 2));        System.out.println(partMap);

collect 执行后果

[1, 2, 3, 2][1, 2, 3]{dd=2, cc=3, bb=2, aa=1}(aa,bb,cc,dd){1=[User{name='aa', age=1}], 2=[User{name='bb', age=2}, User{name='dd', age=2}], 3=[User{name='cc', age=3}]}{1={1=[User{name='aa', age=1}]}, 2={2=[User{name='bb', age=2}, User{name='dd', age=2}]}, 3={3=[User{name='cc', age=3}]}}{false=[User{name='aa', age=1}, User{name='bb', age=2}, User{name='dd', age=2}], true=[User{name='cc', age=3}]}

最初

大家看完有什么不懂的能够在下方留言探讨,也能够关注我私信问我,我看到后都会答复的。也欢送大家关注我的公众号:前程有光,金三银四跳槽面试季,整顿了1000多道将近500多页pdf文档的Java面试题材料,文章都会在外面更新,整顿的材料也会放在外面。谢谢你的观看,感觉文章对你有帮忙的话记得关注我点个赞反对一下!