java8 Stream reduce方法的使用

今天下了JDK 8 EA 尝尝鲜  

摸了好久才摸懂 一些地方 写写文章分享下经验 如有说错欢迎打脸

 

reduce的操作有点麻烦 所以这里就专门说一下

如有说错欢迎打脸...

 

因为java是静态语言所以一些地方自然不如动态语言方便 

比如说我这里有个要求 把0-99的List打印成String输出(当然直接用for也可以啦)

用groovy的话 代码很简单:

def list=0..<100
def sb=list.inject(new StringBuffer(),{result,element -> result.append("${element} ")})

 最后也会用java中 stream的reduce说一遍

 

开始...

 

而java中的reduce操作有三个:

  • 一个参数的
  • 两个参数的
  • 三个参数的_(:3」∠)_


java8 Stream reduce方法的使用_第1张图片
 

 

一个简单是实例 完成累加的操作(当然用mapToInt然后再用sum更好,这里说明用):

 public static void main(String[] args){
   List<Integer> list=new ArrayList<Integer>(); 
   for(int i=0;i<100;i++){
     list.add(Integer.valueOf(i));
   }
   
   System.out.println(list.stream().reduce(
   (result,element)->
        result=result+element));
   
   System.out.println(list.stream().reduce(
   0,
   (result,element)->
        result=result+element));
   

   System.out.println(list.stream().reduce(
   0,
   (result,element)->
        result=result+element
		,(u,t) -> t)); 
   
 }

 结果:

java8 Stream reduce方法的使用_第2张图片

 

在实现中

一个参数是这样实现(近似的实现)的:

     boolean foundAny = false;
     T result = null;
     for (T element : this stream) {
         if (!foundAny) {
             foundAny = true;
             result = element;
         }
         else
             result = accumulator.apply(result, element);
     }
     return foundAny ? Optional.of(result) : Optional.empty();

 实现很简单 初始的result是stream中的某一个值(实际中不是顺序执行的) 之后执行你给的函数就可以了(请把accumulator.apply(result,element) 用自己的函数代替 这里是 result=result+element;

从这里也提醒了函数中参数的位置 聚合用的result是第一个参数 遍历的元素放在第二个参数里

 

二个参数的也同理:

     T result = identity;
     for (T element : this stream)
         result = accumulator.apply(result, element)
     return result;

 因为result用的是自定义的值(要符合泛型的要求) 所以代码短一些

 

三个参数的 对初始值没有泛型的要求:

 

     U result = identity;
     for (T element : this stream)
         result = accumulator.apply(result, element)
     return result;

 看起来和第二个除了在泛型的要求上不一样之外 也没其他什么 但他有个要求

对于第二个函数有限制:

必须满足

  combiner.apply(u, accumulator.apply(identity, t)) == accumulator.apply(u, t)

 但实际使用的时候感觉怪怪的...因为即使有打印信息 并不会有任何输出 但如果这个函数没有返回任何东西无法通过编译.. 实际中直接返回u或者t就可以了(这里有人知道为什么吗..求解),但为了符合以上这个规定,两个函数写得一样好像也没关系.

 

 

只有第三个参数的reduce是不受流的类型限制的 也就是可以返回任意类型的数据 所以三个参数的那个实用性大一点(应该...)

 

现在回到刚开始的问题里

给出代码:

 

import java.util.*;
import java.util.concurrent.*;
import java.util.stream.*;

public class Test4{
 public static void main(String[] args){
   List<Integer> list=new ArrayList<Integer>(); 
   for(int i=0;i<100;i++){
     list.add(Integer.valueOf(i));
   }

   System.out.println(list.stream().reduce(
   new StringBuilder(),
   (result,element)->
        result=result.append(element)
		,(u,t) -> u=u.append(t))); //这个地方 返回 u或者t也是可以的 运行没错
   
 }
}

 

 

 

 

你可能感兴趣的:(Stream)