Java 8-reduce(0,Integer :: sum)和reduce(0,(a,b)-> a + b)之间的区别

时间:2018-10-09 08:07:16

标签: java-8

我是Java 8的新手,确实找到了一些做additionmultiplysubtraction的方法。我将仅添加问题。

我已经编写了以下代码,并在Sum1和Sum2中收集了输出。方法reduce(0, Integer::sum).reduce(0, (a, b) -> a+b);给出相同的结果。明智地使用性能的最佳方法是什么?如果使用大整数值,为什么?

List<Integer> numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4);

Integer sum1 = numbers.stream().reduce(0, (a, b) -> a+b);
System.out.println("SUM ="+sum1);

Integer product = numbers.stream().reduce(0, (a, b) -> a*b);
System.out.println("PRODUCT = "+product);

int sum2 = numbers.stream().reduce(0, Integer::sum);
System.out.println("SUM 2= "+sum2);

Optional<Integer> sum3 = numbers.stream().reduce((a, b) -> (a + b));
System.out.println("SUM3="+sum3);

// Updated as per  @Hadi J comment
int sum4 = numbers.stream().mapToInt(Integer::intValue).sum();
System.out.println("Sum ="+sum4);

1 个答案:

答案 0 :(得分:2)

  

明智地使用性能以及使用大整数值的最佳方法是什么?为什么?

主要思想是在处理基元及其对象表示形式时忽略自动装箱/拆箱。

添加两个Integer对象比添加两个int基元要复杂得多。您可以在this post中找到更多详细信息。

所以最好的情况是,当您有一个原始数组int[]并将其元素求和到类型int的累加器中时。因此,这里没有拳击。

最坏的情况(但不是最坏的情况)是,您将对象Integer与原始元素int相加。这将导致第一个参数的拆箱。 当您的初始数组或集合包含对象(例如Integer [],List等)并且累加器是原始类型时,这就是它的工作方式。这将导致对集合中的每个元素取消装箱一次,而累加器将保持不变。

最坏的情况是将对象集合汇总到Integer累加器中。

  1. 使用普通Java:

    • Integer[]汇总为Integer

      Integer[] array = {0,1,2,3,4,5,6,7,8,9};
      Integer sum = 0;
      // Each element of the array will be unboxed exactly once
      // sum will be unboxed 10 times
      // result of the sum will be boxed 10 times
      for(int i : array) sum += i;
      
    • Integer[]汇总为int

      Integer[] array = {0,1,2,3,4,5,6,7,8,9};
      int sum = 0;
      // Each element of the array will be unboxed exactly once
      // result of the sum will be boxed 10 times
      for(int i : array) sum += i;
      
    • int[]汇总为int

      int[] array = {0,1,2,3,4,5,6,7,8,9};
      int sum = 0;
      // No boxing/unboxing at all
      for(int i : array) sum += i;
      
  2. 流API

    • 减少Stream<Integer>

      的总和
      Stream<Integer> stream = Stream.of(0,1,2,3,4,5,6,7,8,9);
      // Each element will be unboxed exactly once
      // The accumulator will be unboxed 10 times
      // The result of the sum operation will be boxed 10 times
      Integer sum = stream.reduce(0, Integer::sum);
      
    • 减少Stream<Integer>映射到原始int的总和

      Stream<Integer> stream = Stream.of(0,1,2,3,4,5,6,7,8,9);
      // Each element will be unboxed exactly once
      // Neither accumulator not result will be unboxed/boxed
      int sum = stream.mapToInt(Integer::intValue).reduce(0, Integer::sum);
      
    • 减少IntStream

      的总和
      IntStream stream = IntStream.of(0,1,2,3,4,5,6,7,8,9);
      // No boxing/unboxing at all
      int sum = stream.reduce(0, Integer::sum);
      // same as
      int sum2 = stream.sum();