HOWTO · Java

在 Java 中获取数组的总和

了解如何使用循环和流在 Java 中求出数组的总和。

本页内容

在 Java 中计算 int[] 的总和,简洁的内置写法是 Arrays.stream(numbers).sum();如果需要明确控制计算过程,也可以用 for 循环逐个累加。Java 数组本身没有实例 sum() 方法;Arrays.stream(int[]) 会将数组元素转换为 IntStream,后者提供 sum() 和 reduce()。
为数组求和是 Java 教程 中的核心数据操作之一,它把数组与集合指南从基础到流依次排列。

下面的示例使用相同的六个数,其算术总和为 149。每个程序都可以独立运行,并可保存为 SimpleTesting.java。

使用 for 循环计算 int 数组的总和

普通循环会清楚展示每一步:初始化累加器、遍历每个索引,并将对应元素加到累加器中。如果你想逐步跟踪计算过程,或在遍历时加入其他逻辑,这种写法很直接。

下面的程序将 numbers 中的六个值相加并打印总和。循环条件使用 numbers.length,数组名也始终一致地用于获取长度和访问元素。

public class SimpleTesting {
  public static void main(String[] args) {
    int[] numbers = {12, 34, 45, 21, 33, 4};
    int total = 0;

    for (int i = 0; i < numbers.length; i++) {
      total += numbers[i];
    }

    System.out.println("Array Sum = " + total);
  }
}
Array Sum = 149

使用并行流和 reduce 计算 int 数组的总和

对 Arrays.stream(numbers) 返回的 IntStream 调用 parallel(),即可使用并行流。双参数 reduce 接收一个初始值(0)和一个加法操作。由于加法满足结合律,可以合并各部分的合计值,得到相同结果。对于较短的数组,除非并行处理适合周边工作负载,否则优先使用顺序流;并行执行并不会自动让小规模计算更快。

import java.util.Arrays;

public class SimpleTesting {
  public static void main(String[] args) {
    int[] numbers = {12, 34, 45, 21, 33, 4};
    int total = Arrays.stream(numbers)
        .parallel()
        .reduce(0, (left, right) -> left + right);

    System.out.println("Array Sum = " + total);
  }
}
Array Sum = 149

使用 Arrays.stream(...).reduce(...) 计算 int 数组的总和

使用顺序流时,省略 parallel() 即可。Arrays.stream(int[]) 仍会返回 IntStream;reduce(0, Integer::sum) 以初始值为起点,通过加法合并每个基本类型的值。即使没有可合并的值,初始值也能让该操作有明确的结果。

import java.util.Arrays;

public class SimpleTesting {
  public static void main(String[] args) {
    int[] numbers = {12, 34, 45, 21, 33, 4};
    int total = Arrays.stream(numbers).reduce(0, Integer::sum);

    System.out.println("Array Sum = " + total);
  }
}
Array Sum = 149

使用 Arrays.stream(...).sum() 计算 int 数组的总和

当操作是加法时,sum() 比归约操作更直接地表达了意图。它是数组转换所得 IntStream 的终端操作,并返回一个 int 类型的总和。

由于该方法返回 int,总和采用 Java 的 32 位整数运算。如果数学意义上的总和可能超出 int 的范围,应先将流扩宽再求和,例如使用 Arrays.stream(numbers).asLongStream().sum()。普通循环在处理这种范围时,也需要使用 long 累加器,并在相加前将值扩宽。

import java.util.Arrays;

public class SimpleTesting {
  public static void main(String[] args) {
    int[] numbers = {12, 34, 45, 21, 33, 4};
    int total = Arrays.stream(numbers).sum();

    System.out.println("Array Sum = " + total);
  }
}
Array Sum = 149

使用 IntStream.of(...).sum() 计算 int 数组的总和

IntStream.of(numbers) 也是从 int[] 创建 IntStream 的直接方式。它的 sum() 操作返回的总和与 Arrays.stream(numbers).sum() 相同。可以根据哪种写法在代码中读起来更自然来选择。

import java.util.stream.IntStream;

public class SimpleTesting {
  public static void main(String[] args) {
    int[] numbers = {12, 34, 45, 21, 33, 4};
    int total = IntStream.of(numbers).sum();

    System.out.println("Array Sum = " + total);
  }
}
Array Sum = 149

使用简洁的 for 循环计算 int 数组的总和

下面的循环将初始化、继续条件和累加都放在 for 语句头中,然后从数组最后一个索引遍历到第一个索引。这是有效的 Java 写法,但空循环体以及更新表达式中的递减操作,使它比普通循环更难读懂。除非确实需要这种简洁写法,否则建议使用更清晰的形式。

public class SimpleTesting {
  public static void main(String[] args) {
    int[] numbers = {12, 34, 45, 21, 33, 4};
    int total;
    int i;

    for (total = 0, i = numbers.length - 1;
         i >= 0;
         total += numbers[i--]) {
      // Accumulation happens in the loop update expression.
    }

    System.out.println("Array Sum = " + total);
  }
}
Array Sum = 149