java8特性stream流的使用总结

stream的使用 ,让我们的代码更加简洁,易懂(易维护)。它的使用,减少了大量的if条件语句和for循环语句,从输入到输出,像一条河流一样,让维护者读起来更像是读一篇文章。
一个Stream流主要由三部分组成,即数据源、中间操作、终止操作。

1、数据源

常用的创建流方式
a、Stream.of,我们可以通过Stream的静态方法,传入一个泛型数组,或者多个参数,创建一个流。
b、Arrays.stream,我们可以通过Arrays的静态方法,传入一个泛型数组,创建一个流。
c、Collection.stream,可以用过集合的接口的默认方法,创建一个流;使用这个方法,包括继承Collection的接口,如:Set,List,Map等等。

2、中间操作

常用的中间操作,以list.stream()数据源为例

a、filter,过滤流中符合条件的元素。经过list.stream().filter(item->item>0)的操作 ,流中只剩下大于0的item元素。

b、map,元素类型转化。Integer集合list,经过list.stream().map(item->item.toString())的操作 ,流中每个元素转化为了String类型。

c、distinct,流中元素去重。经过list.stream().distinct()操作,流中重复的元素被干掉。特别说明,distinct去重依据的是hashCodeequals方法,如果元素是对象,若要求按照对象的某属性去重需要重写 hashCodeequals方法。

d、sort,流中元素排序。经过list.stream().sort()操作,流中元素被按照自然排序。Student对象组成的list,若要求按照学生的年龄逆序,即list.stream().sorted(Comparator.comparing(Student::getAge).reversed()),使用sort排序的每个元素必须实现Comparable 接口。

e、flatMap,流的扁平化,即降维合并处理。一个List<List<String>>list,经过list.stream().flatMap(item->item.stream())的处理,变为List<String>流。

3、终止操作

常用的终止操作,以list.stream().filter(item->item!=null)中间操作为例

a、forEach,内部迭代。

b、allMatch, anyMatch,noneMatch 匹配,返回Boolean类型,allMatch—检查是否匹配所有元素,anyMatch—检查是否匹配任意元素,noneMatch—检查是否没有匹配所有元素。list.stream().filter(item->item!=null).allMatch(item->item>0)若流中元素全部大于0的返回true,否则返回false。

c、findFirstfindAny 查找,返回Optional<T>类型。list.stream().filter(item->item!=null).findFirst()得到TOptional,若不为null,使用get()方法获取T;或者orElse(null)获取。

d、max、mincountcount()返回元素数量 ,max()min()接收一个Comparator接口参数,返回最大和最小的Optional<T>Stream.of(1, 2,3,4,5).max(Integer::compareTo)获取元素最大的Optional<Integer>,再使用get()可以得到5。
补充:当max有多条记录时,取流的第1条。max用了BinaryOperator的maxBy方法。具体参照源码:

    public static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator) {
        Objects.requireNonNull(comparator);
        return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
    }

e、reduce 归约
接收一个参数:Stream.of(1,2,3,4,5).reduce((a,b)->a+b),结果类型为Optional<Integer>,调用get()方法得到15。
接收两个参数:Stream.of(1, 2, 3, 4, 5).reduce(5, (a, b) -> a + b),结果类型为Integer,值为20,第一个参数为初始值 。
接收三个参数:Stream.of(1, 2, 3, 4, 5).parallel().reduce(0, (a, b) -> a + b, (s1, s2) -> s1 + s2),第三个参数只有在并行流中才会执行 ,作用是将并行每个流的运算结果按照第三个参数的运算规则进行最终合并。

f、collect 收集,该方法功能比较强大,能将流收集成很多形式。collect方法接收的多个参数中最主要有一个Collector接口。
收集为Listlist.stream().filter(item->item!=null).collect(Collectors.toList())
收集为Setlist.stream().filter(item->item!=null).collect(Collectors.toSet())
收集为HashSetlist.stream().filter(item->item!=null).collect(Collectors.toCollection(HashSet::new))
收集为Map,接收两个参数:list.stream().filter(item->item!=null).collect(Collectors.toMap(item1->item1.getKey(),item2->item2)),第一个参数设置map的key,第二个参数设置map的value,此时应注意key值必须唯一,否则会抛异常。key唯一下面Guava写法效果相同:Maps.uniqueIndex(list, item->item.getKey()),得到的结果都是Map<String,T>类型。
接收三个参数:list.stream().filter(item->item!=null).collect(Collectors.toMap(item1->item1.getKey(),item2->item2,(val1,val2)->val2)),前两个参数同上,第三个参数为map的value合并函数。上面表达式表示当出现相同的key时,value取后者。
接收四个参数:list.stream().filter(item->item!=null).collect(Collectors.toMap(item1->item1.getKey(),item2->item2,(val1,val2)->val2,LinkedHashMap::new)),前三个参数同上,第四个参数表示设置接收map的容器为LinkedHashMap。该参数不设置的情况下默认为HashMap
多级分组groupingBy:接收一个参数:list.stream().filter(item->item!=null).collect(Collectors.groupingBy(item1->item1.getKey())),按照key分组,得到Map<String,List<T>>类型结果。
接收两个参数:list.stream().filter(item->item!=null).collect(Collectors.groupingBy(item->item.getKey(),Collectors.mapping(item->new U(item.getKey(),item),Collectors.toList())))
第二个参数重新定义了map的value收集类型,得到Map<String,List<U>>类型结果。
上面Map<String,List<U>>结果也可以使用toMap实现:list.stream().filter(item->item!=null).collect(Collectors.toMap(item->item.getKey(),item -> Stream.of(new U(item.getKey(), item)).collect(Collectors.toList()),(a, b) -> Stream.concat(a.stream(), b.stream()).collect(Collectors.toList())))

//待补充…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值