115

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);
4
  • 3
    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. Commented May 11, 2011 at 12:02
  • 1
    The PHP function array_sum also does a loop internally, it just hides it from the user. Commented May 11, 2011 at 13:01
  • 3
    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. Commented Mar 13, 2014 at 21:08
  • 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. Commented Jun 29, 2021 at 10:40

13 Answers 13

203

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();
Sign up to request clarification or add additional context in comments.

3 Comments

map uses loops implicitly
You could use recursion to not use a loop. :D (don't do this)
stream is too much slow, shit...
27

Then write it yourself:

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

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

     return sum;
}

2 Comments

Or extending ArrayList with the sum method so you have it built in to your own ArrayList.
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.
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

2 Comments

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 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.
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)

1 Comment

but how can i do it for long value in arraylist ?
9

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.

1 Comment

This is the most clear and objetive answer for this kind of operation.
3

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);

Comments

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();
}

Comments

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;

2 Comments

You are right. I said it's a minimal loop instead of map which can be tail recursive.
"Is there possibility of sum of ArrayList without looping"
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.

Comments

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?

Comments

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.

2 Comments

Yeah. Sum function is definitely reason to switch to another language. :D
The question is tagged Java, so this is technically not a valid answer.
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

Comments

0

You can use GNU Trove library:

TIntList tt = new TIntArrayList();
tt.add(1);
tt.add(2);
tt.add(3);
int sum = tt.sum();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.