如何在Java中计算数组中所有数字的总和?

194

我在Java中遇到了一个问题,无法找到求一个数组中所有整数的和的有用方法,Math类中也没有这个方法。


18
编写自己的代码,它只需2-3行即可完成。 - wkl
2
不幸的是,上述(以及以下)的“答案”都是“Java方式” :-/ 您可以使用Functional Java库,但处理Java语法非常繁琐。 - user166390
2
我知道这个问题非常古老,但下面的msayag的答案似乎应该被标记为被接受的答案。 - Matsu Q.
编写自己的代码的问题在于它是一个循环。当你对3个数字求和时,应该能够在一条指令中完成。 - Al G Johnston
29个回答

334

中,你可以使用流:

int[] a = {10,20,30,40,50};
int sum = IntStream.of(a).sum();
System.out.println("The sum is " + sum);

输出:

和为150。

它位于包java.util.stream中。

import java.util.stream.*;

1
如果数组包含大数且总和超出了int范围怎么办? - thanhbinh84
8
在这种情况下,您可以使用LongStream,可以写成long sum = IntStream.of(a).asLongStream().sum();或者long sum = LongStream.of(a).sum();。 - msayag
3
使用流(Streams)是否有明显的速度优势? - mvorisek
1
如果您的总和不适合长整型,应该逐对求和(分而治之),因为较小的BigDecimal求和更快。 - user482745
你有解决方案可以在一个double数组上执行相同的操作吗?如果你尝试在一个double上执行它,你会得到错误信息:"method java.util.stream.IntStream.of(int...) is not applicable (varargs mismatch; double[] cannot be converted to int)"。 - M.Hossein Rahimi
1
@HosseinRahimi java.util.stream.DoubleStream.of(a).sum(); - ggorlen

72
如果您使用的是Java 8,Arrays类提供了一个stream(int[] array)方法,该方法返回具有指定int数组的顺序IntStream。 它还为doublelong数组进行了重载。请注意保留HTML标签。
int [] arr = {1,2,3,4};
int sum = Arrays.stream(arr).sum(); //prints 10

它还提供了一种方法stream(int[] array, int startInclusive, int endExclusive),允许您获取数组的指定范围(这可能非常有用):
int sum = Arrays.stream(new int []{1,2,3,4}, 0, 2).sum(); //prints 3

最后,它可以接受类型为T的数组。例如,如果您有一个包含数字的String作为输入,如果想要对它们求和,只需执行以下操作:
int sum = Arrays.stream("1 2 3 4".split("\\s+")).mapToInt(Integer::parseInt).sum();

41
这是一些简单的事情,在标准Java API中(据我所知)并不存在。很容易编写自己的代码。
其他答案也很好,但这里有一个使用for-each语法糖的示例。
int someArray[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int sum = 0;

for (int i : someArray)
    sum += i;

此外,Java 7语言规范中甚至展示了数组求和的示例。该示例来自第10.4节 - 数组访问

class Gauss {
    public static void main(String[] args) {
        int[] ia = new int[101];
        for (int i = 0; i < ia.length; i++) ia[i] = i;
        int sum = 0;
        for (int e : ia) sum += e;
        System.out.println(sum);
    }
}

但是这并不会一次性将所有数字相加。这是低效的。 - Al G Johnston
4
我无法想象它会比streams解决方案效率更低。 - Dawood ibn Kareem
绝对没有比将所有数字相加更好的方法来确定任意一组数字的总和。O(n)是你所能做到的最好方法。 - Arfur Narf

22

你无法这样做。其他编程语言有一些方法可以实现,比如 PHP 中的 array_sum() 函数,但 Java 不支持。

只是...

int[] numbers = {1,2,3,4};
int sum = 0;
for( int i : numbers) {
    sum += i;
}

System.out.println(sum);

7
我想念你。.NET Sum(IEnumerable<Int32>)的意思是对Int32类型的集合进行求和。有关详情可参考http://msdn.microsoft.com/en-us/library/system.linq.enumerable.sum.aspx。 - Akira Yamamoto

15
在Apache Math中:有一个StatUtils.sum(double[] arr)函数。

为什么只在statutils中:D - Lore

14

我对之前的解决方案唯一要补充的是,我会使用long类型来累加总和,以避免数值溢出。

int[] someArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, Integer.MAX_VALUE};
long sum = 0;

for (int i : someArray)
    sum += i;

8
int sum = 0;

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

4
你可以使用 for-each 循环(Java 1.5 中引入)使它更加简洁。 - wkl

7
在Java 8中,
代码:
   int[] array = new int[]{1,2,3,4,5};
   int sum = IntStream.of(array).reduce( 0,(a, b) -> a + b);
   System.out.println("The summation of array is " + sum);

  System.out.println("Another way to find summation :" + IntStream.of(array).sum());

输出:

The summation of array is 15
Another way to find summation :15

解释:

Java 8中,你可以使用“Reduction”概念来进行加法计算。

阅读有关Reduction的全部信息


5
int sum = 0;
for (int i = 0; i < myArray.length; i++)
  sum += myArray[i];
}

5
这要看情况。您要加多少个数字?测试了上述建议的许多选项:
import java.text.NumberFormat;
import java.util.Arrays;
import java.util.Locale;

public class Main {

    public static final NumberFormat FORMAT = NumberFormat.getInstance(Locale.US);

    public static long sumParallel(int[] array) {
        final long start = System.nanoTime();
        int sum = Arrays.stream(array).parallel().reduce(0,(a,b)->  a + b);
        final long end = System.nanoTime();
        System.out.println(sum);
        return  end - start;
    }

    public static long sumStream(int[] array) {
        final long start = System.nanoTime();
        int sum = Arrays.stream(array).reduce(0,(a,b)->  a + b);
        final long end = System.nanoTime();
        System.out.println(sum);
        return  end - start;
    }

    public static long sumLoop(int[] array) {
        final long start = System.nanoTime();
        int sum = 0;
        for (int v: array) {
            sum += v;
        }
        final long end = System.nanoTime();
        System.out.println(sum);
        return  end - start;
    }

    public static long sumArray(int[] array) {
        final long start = System.nanoTime();
        int sum = Arrays.stream(array) .sum();
        final long end = System.nanoTime();
        System.out.println(sum);
        return  end - start;
    }

    public static long sumStat(int[] array) {
        final long start = System.nanoTime();
        int sum = 0;
        final long end = System.nanoTime();
        System.out.println(sum);
        return  end - start;
    }


    public static void test(int[] nums) {
        System.out.println("------");
        System.out.println(FORMAT.format(nums.length) + " numbers");
        long p = sumParallel(nums);
        System.out.println("parallel " + FORMAT.format(p));
        long s = sumStream(nums);
        System.out.println("stream " +  FORMAT.format(s));
        long ar = sumArray(nums);
        System.out.println("arrays " +  FORMAT.format(ar));
        long lp = sumLoop(nums);
        System.out.println("loop " +  FORMAT.format(lp));

    }

    public static void testNumbers(int howmany) {
        int[] nums = new int[howmany];
        for (int i =0; i < nums.length;i++) {
            nums[i] = (i + 1)%100;
        }
        test(nums);
    }

    public static void main(String[] args) {
        testNumbers(3);
        testNumbers(300);
        testNumbers(3000);
        testNumbers(30000);
        testNumbers(300000);
        testNumbers(3000000);
        testNumbers(30000000);
        testNumbers(300000000);
    }
}

我发现,在一台8核16G的Ubuntu18机器上,循环对于较小的值速度更快,而并行对于较大的值更快。但当然这取决于你运行的硬件:

------
3 numbers
6
parallel 4,575,234
6
stream 209,849
6
arrays 251,173
6
loop 576
------
300 numbers
14850
parallel 671,428
14850
stream 73,469
14850
arrays 71,207
14850
loop 4,958
------
3,000 numbers
148500
parallel 393,112
148500
stream 306,240
148500
arrays 335,795
148500
loop 47,804
------
30,000 numbers
1485000
parallel 794,223
1485000
stream 1,046,927
1485000
arrays 366,400
1485000
loop 459,456
------
300,000 numbers
14850000
parallel 4,715,590
14850000
stream 1,369,509
14850000
arrays 1,296,287
14850000
loop 1,327,592
------
3,000,000 numbers
148500000
parallel 3,996,803
148500000
stream 13,426,933
148500000
arrays 13,228,364
148500000
loop 1,137,424
------
30,000,000 numbers
1485000000
parallel 32,894,414
1485000000
stream 131,924,691
1485000000
arrays 131,689,921
1485000000
loop 9,607,527
------
300,000,000 numbers
1965098112
parallel 338,552,816
1965098112
stream 1,318,649,742
1965098112
arrays 1,308,043,340
1965098112
loop 98,986,436

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接