Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

260
Views
Is it possible to calculate values in a stream based on themselves

If I have a java stream of e.g. numbers, is it possible to calculate e.g. the sums up to that number (by adding the number to the "previously" calculated sum)?

e.g. (1, 2, 3, 5, 7, 9, 0) --> (1, 3, 6, 11, 18, 27, 27)

over 4 years ago · Santiago Trujillo
4 answers
Answer question

0

A simple solution using Streams is to use reducing. This solution is not stateless, though.

var inputList = List.of(1, 2, 3, 5, 7, 9, 0);
var result = new ArrayList<>();

var unused = inputList.stream().collect(reducing(0, (a, b) -> {
    result.add(a + b);
    return a + b;
}));

System.out.println(result); // [1, 3, 6, 11, 18, 27, 27]

A few points:

  • Mutation should always be avoided while using streams. Streams are not meant to replace imperative code.
  • Above solution doesn't have room for parallelism
  • Streams API introduces the functional programming (what to do) paradigm in Java. It is not supposed to be mixed with imperative (how to do) code.
  • The parallelPrefix solution in Faeemazaz Bhanej answer should be the preferred solution
over 4 years ago · Santiago Trujillo Report

0

yes, you can use a custom collector to do that. Although the "stream" part would have nothing to do.

It would look like list.stream().collect( new CustomSequentialCollector() )

over 4 years ago · Santiago Trujillo Report

0

You have to use parallelPrefix for sum of array in java stream.

Integer[] arr = {1, 2, 3, 5, 7, 9, 0};
Arrays.parallelPrefix(arr, (x, y) -> x + y);
System.out.println(Arrays.toString(arr));

You have to use AtomicInteger for ArrayList

List<Integer> list = new ArrayList<>();
list.addAll(Arrays.asList(1, 2, 3, 5, 7, 9, 0));
        
AtomicInteger ai = new AtomicInteger();
List<Integer> sumOfList = list.stream()
                              .map(ai::addAndGet)
                              .collect(Collectors.toList());
System.out.println(sumOfList);
over 4 years ago · Santiago Trujillo Report

0

Here is a proof of concept building on this answer. It implements a fully stateless solution with O(n) time complexity that also works with parallel streams.

    record CumSum(Integer acc, List<Integer> sums) {
        public CumSum() {
            this(0, List.of());
        }

        public CumSum collect(Integer n) {
            return new CumSum(acc + n, concat(sums, Stream.of(acc + n)));
        }

        public CumSum combine(CumSum cumSum) {
            return new CumSum(acc + cumSum.acc, concat(sums, cumSum.sums.stream().map(n -> acc + n)));
        }

        private static List<Integer> concat(List<Integer> sums, Stream<Integer> acc) {
            return Stream.concat(sums.stream(), acc).toList();
        }
    }

    var list1 = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
    var list2 = list1.stream().parallel()
        .reduce(new CumSum(), CumSum::collect, CumSum::combine)
        .sums;

    System.out.println(list2);

The output is

[1, 3, 6, 10, 15, 21, 28, 36, 45, 55]

regardless of using a parallel stream or not.

Note that due to the lack of a true immutable List in Java, CumSum jumps back and forth from List and Stream, which complicates this implementation unnecessarily. Also the separate tracking in acc could be replaced by just looking at the last element in sums. For more clarity I chose not to do that.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!