Java8——Stream流的使用(归纳操作)

在集合、数组操作中,我们有时候需要对集合的元素进行一个整体的统计,特别是求和、求差、求最值、计数等等计算操作,这些操作需要使用每一个元素,最后返回唯一的一个结果,这样的操作称为“归纳”,Stream API提供了reduce、max、min等方法来完成归纳操作!

  在集合、数组操作中,我们有时候需要对集合的元素进行一个整体的统计,特别是求和、求差、求最值、计数等等计算操作,这些操作需要使用每一个元素,最后返回唯一的一个结果,这样的操作称为“归纳”,Stream API提供了reduce、max、min等方法来完成归纳操作!
  归纳操作是一个终端操作!

Optional< T > reduce(BinaryOperator< T > accumulator)

  没有初始值,返回一个Optional对象,以表明结果可能不存在。
  accumulator:二元操作器,操作两个元素得到一个新元素。第一次计算时两个参数分别取前两个元素,计算的值将会作为下一次计算的第一个参数,后面的元素作为第二个参数,以此类推,最终会返回计算结果。

T reduce(T identity, BinaryOperator< T > accumulator)

  identity:一个初始值,最终会返回同类型的值。
  accumulator:二元操作器,操作两个元素得到一个新元素。串行模式下:第一次计算时第一个参数取初始值,第二个参数取第一个元素,计算的值将会作为下一次计算的第一个参数,后面的元素作为第二个参数,以此类推,最终会返回计算结果。并行模式下:对初始值和每一个元素应用一次accumulator函数(初始值为第一个参数,流元素为第二个参数),会得到对应个数的结果,最后通过accumulator再一次整合,即对第一轮accumulator获得的结果在应用一轮accumulator!

< U > U reduce(U identity,BiFunction< U,? super T,U > accumulator,BinaryOperator< U > combiner)

  identity:一个初始值,最终会返回同类型的值。
  accumulator: 一个二元函数,操作两个元素得到一个新元素。串行模式下:第一次计算时第一个参数取初始值,第二个参数取第一个元素,计算的值将会作为下一次计算的第一个参数,后面的元素作为第二个参数,以此类推,最终会返回计算结果。并行模式下:对初始值和每一个元素应用一次accumulator函数(初始值为第一个参数,流元素为第二个参数),会得到对应元素个数的结果,最后通过combiner整合!
  combiner:二元操作器,并行模式下第三个参数才会生效。在并行模式下初始值会和每一个流元素进行一次accumulator计算(初始值为第一个参数,流元素为第二个参数),随后会通过combiner对这些计算结果进行整合,最后返回整合后的结果!

使用案例:

/**
 * @author lx
 */
public class ReduceTest {


    /**
     * 求差
     * 验证二元操作器的参数关系
     */
    @Test
    public void subtract() {
        //Optional< T > reduce(BinaryOperator< T > accumulator);
        //求差  前一个计算的值减去后一个元素
        Optional<Integer> subtractReduce1 = Stream.of(1, 2, 3, 4, 7)
                .reduce((i, j) -> i - j);
        subtractReduce1.ifPresent(System.out::println);

        //Optional< T > reduce(BinaryOperator< T > accumulator);
        //求差  后一个元素减去前一个计算的值
        Optional<Integer> subtractReduce2 = Stream.of(1, 2, 3, 4, 7)
                .reduce((i, j) -> j - i);
        subtractReduce2.ifPresent(System.out::println);
    }


    @Test
    public void test() {
        //Optional< T > reduce(BinaryOperator< T > accumulator);
        //求和
        Optional<Integer> sumReduce = Stream.of(1, 2, 3, 4, 7)
                //使用方法引用Integer::sum来表示求和的意图
                .reduce(Integer::sum);
        sumReduce.ifPresent(System.out::println);


        //Optional< T > reduce(BinaryOperator< T > accumulator);
        //求最值
        Optional<Integer> maxReduce = Stream.of(1, 2, 3, 4, 7)
                //使用方法引用Integer::max来表示求最值的意图
                .reduce(Integer::max);
        maxReduce.ifPresent(System.out::println);


        //T reduce(T identity, BinaryOperator< T > accumulator);
        //求最值,初始值10
        System.out.println(Stream.of(1, 2, 3, 4, 7)
                //使用方法引用Integer::max来表示求最值的意图
                .reduce(10, Integer::max));

        //T reduce(T identity, BinaryOperator< T > accumulator);
        //计数
        System.out.println(Stream.of(1, 2, 3, 4, 7)
                .map(d -> 1)
                .reduce(0, Integer::sum));
        //更简单的方法,内部使用的数值流,内部实际上是特性化的流操作,后面会讲
        System.out.println(Stream.of(1, 2, 3, 4, 7).count());
    }


    /**
     * < U > U reduce(U identity,BiFunction<U,? super T,U> accumulator,BinaryOperator< U > combiner)
     * 复杂计算
     */
    @Test
    public void test2() {

        //串行模式下无效
        System.out.println(Stream.of(1, 2, 3, 4, 7).reduce(2, Integer::sum, Integer::sum));
        System.out.println(Stream.of(1, 2, 3, 4, 7).reduce(2, Integer::sum, Integer::max));

        //并行模式下有效
        //初始值为2,首先对每一个元素应用一个计算accumulator,得到结果:3,4,5,6,9,最后combiner整合这些值:得到27
        System.out.println(Stream.of(1, 2, 3, 4, 7).parallel().reduce(2, Integer::sum, Integer::sum));
        //初始值为2,首先对每一个元素应用一个计算accumulator,得到结果:3,4,5,6,9,最后combiner整合这些值:得到9
        System.out.println(Stream.of(1, 2, 3, 4, 7).parallel().reduce(2, Integer::sum, Integer::max));
        //初始值为2,首先对每一个元素应用一个计算accumulator,得到结果:1,2,3,4,7,最后combiner整合这些值:得到1
        System.out.println(Stream.of(1, 2, 3, 4, 7).parallel().reduce(0, Integer::sum, Integer::min));

        //初始值为2,首先对每一个元素应用一个计算accumulator,得到结果:-1,0,1,2,5,最后combiner整合这些值:得到7
        System.out.println(Stream.of(1, 2, 3, 4, 7).parallel().reduce(2, (i, j) -> j - i, Integer::sum));
        //初始值为2,首先对每一个元素应用一个计算accumulator,得到结果:1,0,-1,-2,-5,最后combiner整合这些值:得到-7
        System.out.println(Stream.of(1, 2, 3, 4, 7).parallel().reduce(2, (i, j) -> i - j, Integer::sum));


        System.out.println(Stream.of(1, 2, 3, 4, 7).parallel().reduce(2, (i, j) -> {
                    //查看线程,多线程
                    System.out.println(Thread.currentThread().getName());
                    return j - i;
                }
                , Integer::sum));

        System.out.println(Stream.of(1, 2, 3, 4, 7).reduce(2, (i, j) -> {
                    //查看线程,单线程
                    System.out.println(Thread.currentThread().getName());
                    return j - i;
                }
                , Integer::sum));
    }
}

  • 发表于 2020-09-16 16:06
  • 阅读 ( 17 )

0 条评论

请先 登录 后评论
NX小编
NX小编

973 篇文章

作家榜 »

  1. NX小编 973 文章
  2. 58沈剑 309 文章
  3. 奈学教育 130 文章
  4. 李希沅 | 奈学教育 25 文章
  5. 江帅帅 | 奈学教育 24 文章
  6. 林淮川 | 奈学教育 12 文章
  7. 科技热点 10 文章
  8. 邱鹏超 2 文章