109

Is there possibility of sum of ArrayList without looping?

PHP provides sum(array) which will give the sum of array.

The PHP code is like

$a = array(2, 4, 6, 8);
echo "sum(a) = " . array_sum($a) . "\n";

I wanted to do the same in Java:

List tt = new ArrayList();
tt.add(1);
tt.add(2);
tt.add(3);
Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
Tapsi
  • 1,197
  • 3
  • 9
  • 10
  • 2
    What if the `ArrayList` doesn not contain something that is "summable"? ArrayList and an array isn't necessarily the same thing. As for summing numbers in an array, that's a very simple for loop over the elements and calculating a cumulative sum. – posdef May 11 '11 at 12:02
  • The PHP function `array_sum` also does a loop internally, it just hides it from the user. – Paŭlo Ebermann May 11 '11 at 13:01
  • 2
    It's a reasonable question. After all, it's nearly as trivial to write a loop to find the largest element in a list, yet java.util.Collections provides a max() method. – John Velonis Mar 13 '14 at 21:08
  • 1
    Very reasonable question, after all, that's the point of methods, right? Reuse :) – Ben Taliadoros Jul 25 '14 at 15:11
  • 1
    Loops are beautiful. – Alex78191 Sep 27 '18 at 13:15
  • I suggest the answer provided by Ján Яabčan. I don't know why his answer isn't the most upvoted one, since it provides the most clear and objetive method to accomplish your sum. – Pelicer Jun 29 '21 at 10:40

13 Answers13

192

Once is out (March 2014) you'll be able to use streams:

If you have a List<Integer>

int sum = list.stream().mapToInt(Integer::intValue).sum();

If it's an int[]

int sum = IntStream.of(a).sum();
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
msayag
  • 8,407
  • 4
  • 30
  • 29
27

Then write it yourself:

public int sum(List<Integer> list) {
     int sum = 0; 

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

     return sum;
}
Community
  • 1
  • 1
Erhan Bagdemir
  • 5,231
  • 6
  • 34
  • 40
  • 1
    Or extending ArrayList with the sum method so you have it built in to your own ArrayList. – Bueller May 11 '11 at 12:03
  • 3
    When doing the actual addition, it's just nicer to use a simple `int`. There is little value in using `Integer` with java's auto-boxing features here. Also, you are creating and recreating potentially many new `Integer` objects each time, since it is an `Immutable` type. – Java Drinker May 11 '11 at 12:37
11

The only alternative to using a loop is to use recursion.

You can define a method like

public static int sum(List<Integer> ints) {
   return ints.isEmpty() ? 0 : ints.get(0) + ints.subList(1, ints.length());
}

This is very inefficient compared to using a plain loop and can blow up if you have many elements in the list.

An alternative which avoid a stack overflow is to use.

public static int sum(List<Integer> ints) {
    int len = ints.size();
    if (len == 0) return 0;
    if (len == 1) return ints.get(0);
    return sum(ints.subList(0, len/2)) + sum(ints.subList(len/2, len));
}

This is just as inefficient, but will avoid a stack overflow.


The shortest way to write the same thing is

int sum = 0, a[] = {2, 4, 6, 8};

for(int i: a) {
    sum += i;
}

System.out.println("sum(a) = " + sum);

prints

sum(a) = 20
Mel Kicchi
  • 188
  • 1
  • 12
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • In the code you miss the call to sum() in the first recursive definition. The second recursive definition does not prevent stack overflow from happening, it makes it less likely. – Teudimundo Dec 03 '15 at 13:47
  • 1
    @Teudimundo True, While it doesn't prevent it, the maximum size of a List is Integer.MAX_VALUE and the log2 is 31 which is maximum depth. Most systems have many thousands of calls as a limit but if you are very close to the this it could still blow. – Peter Lawrey Dec 03 '15 at 14:02
9

Write a util function like

public class ListUtil{

    public static int sum(List<Integer> list){
      if(list==null || list.size()<1)
        return 0;

      int sum = 0;
      for(Integer i: list)
        sum = sum+i;

      return sum;
    }
}

Then use like

int sum = ListUtil.sum(yourArrayList)
Nishant
  • 54,584
  • 13
  • 112
  • 127
8

for me the clearest way is this:

doubleList.stream().reduce((a,b)->a+b).get();

or

doubleList.parallelStream().reduce((a,b)->a+b).get();

It also use internal loops, but it is not possible without loops.

Ján Яabčan
  • 743
  • 2
  • 10
  • 20
2

You can use apache commons-collections API.

class AggregateClosure implements org.apache.commons.collections.Closure {
        int total = 0;

        @Override
        public void execute(Object input) {
            if (input != null) {
                total += (Integer) input;
            }
        }

        public int getTotal() {
            return total;
        }
    }

Then use this closure as shown below:

public int aggregate(List<Integer> aList) {
        AggregateClosure closure = new AggregateClosure();
        org.apache.commons.collections.CollectionUtils.forAllDo(aList, closure);
        return closure.getTotal();
}
Hari Samala
  • 159
  • 1
  • 4
2

This can be done with reduce using method references reduce(Integer::sum):

Integer reduceSum = Arrays.asList(1, 3, 4, 6, 4)
        .stream()
        .reduce(Integer::sum)
        .get();

Or without Optional:

Integer reduceSum = Arrays.asList(1, 3, 4, 6, 4)
        .stream()
        .reduce(0, Integer::sum);
lczapski
  • 4,026
  • 3
  • 16
  • 32
1

If you know about the map function, then you know that a map is also can be recursive loop or recursive loop. But obviously you have to reach each element for that. so, I could not work out the Java 8, because some syntax mismatch but wanted a very short so this is what I got.

int sum = 0
for (Integer e : myList) sum += e;
sivi
  • 10,654
  • 2
  • 52
  • 51
0

Or switch to Groovy, it has a sum() function on a collection. [1,2,3,4,5,6].sum()

http://groovy.codehaus.org/JN1015-Collections

Runs on the same JVM as your java classes.

dbrin
  • 15,525
  • 4
  • 56
  • 83
0

This link shows three different ways how to sum in java, there is one option that is not in previous answers using Apache Commons Math..

Example:

public static void main(String args []){
    List<Double> NUMBERS_FOR_SUM = new ArrayList<Double>(){
         {
            add(5D);
            add(3.2D);
            add(7D);
         }
    };
    double[] arrayToSume = ArrayUtils.toPrimitive(NUMBERS_FOR_SUM
            .toArray(new Double[NUMBERS_FOR_SUM.size()]));    
    System.out.println(StatUtils.sum(arrayToSume));

}

See StatUtils api

nachokk
  • 14,363
  • 4
  • 24
  • 53
0

You can use GNU Trove library:

TIntList tt = new TIntArrayList();
tt.add(1);
tt.add(2);
tt.add(3);
int sum = tt.sum();
yurez
  • 2,826
  • 1
  • 28
  • 22
0

Given that a list can hold any type of object, there is no built in method which allows you to sum all the elements. You could do something like this:

int sum = 0;

for( Integer i : ( ArrayList<Integer> )tt ) {
  sum += i;
}

Alternatively you could create your own container type which inherits from ArrayList but also implements a method called sum() which implements the code above.

Mike Kwan
  • 24,123
  • 12
  • 63
  • 96
0

ArrayList is a Collection of elements (in the form of list), primitive are stored as wrapper class object but at the same time i can store objects of String class as well. SUM will not make sense in that. BTW why are so afraid to use for loop (enhanced or through iterator) anyways?

GauravJ
  • 2,162
  • 1
  • 22
  • 28