Cumulative Sum using Java 8 stream APIHow does newly introduced Arrays.parallelPrefix(…) in Java 8 work?Map to a running sum in Java 8Is Java “pass-by-reference” or “pass-by-value”?How do I efficiently iterate over each entry in a Java Map?What is the difference between public, protected, package-private and private in Java?How do I read / convert an InputStream into a String in Java?When to use LinkedList over ArrayList in Java?How do I generate random integers within a specific range in Java?How do I convert a String to an int in Java?Creating a memory leak with JavaJava 8 List<V> into Map<K, V>How to Convert a Java 8 Stream to an Array?

Why is it that the natural deduction method can't test for invalidity?

Examples of subgroups where it's nontrivial to show closure under multiplication?

Does holding a wand and speaking its command word count as V/S/M spell components?

How exactly does Hawking radiation decrease the mass of black holes?

Why must Chinese maps be obfuscated?

Is this homebrew Wind Wave spell balanced?

Combinable filters

What's the polite way to say "I need to urinate"?

Is the 5 MB static resource size limit a 5,242,880 bytes limit or a 5,000,000 bytes limit?

In order to check if a field is required or not, is the result of isNillable method sufficient?

What software provides a code editing environment on iPad?

What language was spoken in East Asia before Proto-Turkic?

Do I have to worry about players making “bad” choices on level up?

how to find the equation of a circle given points of the circle

How can I practically buy stocks?

Realistic Necromancy?

What are the potential pitfalls when using metals as a currency?

Don’t seats that recline flat defeat the purpose of having seatbelts?

Why does nature favour the Laplacian?

Minor Revision with suggestion of an alternative proof by reviewer

Can I spend a night at Vancouver then take a flight to my college in Toronto as an international student?

How could Tony Stark make this in Endgame?

Does Gita support doctrine of eternal cycle of birth and death for evil people?

Is there an official tutorial for installing Ubuntu 18.04+ on a device with an SSD and an additional internal hard drive?



Cumulative Sum using Java 8 stream API


How does newly introduced Arrays.parallelPrefix(…) in Java 8 work?Map to a running sum in Java 8Is Java “pass-by-reference” or “pass-by-value”?How do I efficiently iterate over each entry in a Java Map?What is the difference between public, protected, package-private and private in Java?How do I read / convert an InputStream into a String in Java?When to use LinkedList over ArrayList in Java?How do I generate random integers within a specific range in Java?How do I convert a String to an int in Java?Creating a memory leak with JavaJava 8 List<V> into Map<K, V>How to Convert a Java 8 Stream to an Array?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








11















I have a List of Integer say list1, and I want to get another list list2 which will contain the cumulative sum up until the current index from start. How can I do this using Stream API java 8 ?



List<Integer> list1 = new ArrayList<>();
list1.addAll(Arrays.asList(1, 2, 3, 4));
List<Integer> list2 = new ArrayList<>();
// initialization
list2.add(list1.get(0));
for(int i=1;i<list1.size();i++)
// increment step
list2.add(list2.get(i-1) + list1.get(i));



How can I change above imperative style code into declarative one ?



list2 should be [1, 3, 6, 10]









share|improve this question



















  • 11





    You'll notice from the answers that any solution using streams is going to be inefficient. Streams aren't really intended for this use case. (In general, streams aren't intended to replace all imperative code.)

    – Louis Wasserman
    Mar 20 at 16:48











  • @LouisWasserman I agree. But in this case I do not care about efficiency (probably should have mentioned it in the question). I wanted to write the same thing with something other than above mentioned imperative style. I could not do it myself, as I was stuck because the solution is kind of mixture of map and reduce operation

    – run_time_error
    Mar 20 at 17:17











  • Man, the lack of tuples really hurts here.

    – Alexander
    Mar 20 at 22:19






  • 2





    An extremely similar question was asked yesterday: stackoverflow.com/questions/55230261/…

    – Jacob G.
    Mar 21 at 0:41

















11















I have a List of Integer say list1, and I want to get another list list2 which will contain the cumulative sum up until the current index from start. How can I do this using Stream API java 8 ?



List<Integer> list1 = new ArrayList<>();
list1.addAll(Arrays.asList(1, 2, 3, 4));
List<Integer> list2 = new ArrayList<>();
// initialization
list2.add(list1.get(0));
for(int i=1;i<list1.size();i++)
// increment step
list2.add(list2.get(i-1) + list1.get(i));



How can I change above imperative style code into declarative one ?



list2 should be [1, 3, 6, 10]









share|improve this question



















  • 11





    You'll notice from the answers that any solution using streams is going to be inefficient. Streams aren't really intended for this use case. (In general, streams aren't intended to replace all imperative code.)

    – Louis Wasserman
    Mar 20 at 16:48











  • @LouisWasserman I agree. But in this case I do not care about efficiency (probably should have mentioned it in the question). I wanted to write the same thing with something other than above mentioned imperative style. I could not do it myself, as I was stuck because the solution is kind of mixture of map and reduce operation

    – run_time_error
    Mar 20 at 17:17











  • Man, the lack of tuples really hurts here.

    – Alexander
    Mar 20 at 22:19






  • 2





    An extremely similar question was asked yesterday: stackoverflow.com/questions/55230261/…

    – Jacob G.
    Mar 21 at 0:41













11












11








11


5






I have a List of Integer say list1, and I want to get another list list2 which will contain the cumulative sum up until the current index from start. How can I do this using Stream API java 8 ?



List<Integer> list1 = new ArrayList<>();
list1.addAll(Arrays.asList(1, 2, 3, 4));
List<Integer> list2 = new ArrayList<>();
// initialization
list2.add(list1.get(0));
for(int i=1;i<list1.size();i++)
// increment step
list2.add(list2.get(i-1) + list1.get(i));



How can I change above imperative style code into declarative one ?



list2 should be [1, 3, 6, 10]









share|improve this question
















I have a List of Integer say list1, and I want to get another list list2 which will contain the cumulative sum up until the current index from start. How can I do this using Stream API java 8 ?



List<Integer> list1 = new ArrayList<>();
list1.addAll(Arrays.asList(1, 2, 3, 4));
List<Integer> list2 = new ArrayList<>();
// initialization
list2.add(list1.get(0));
for(int i=1;i<list1.size();i++)
// increment step
list2.add(list2.get(i-1) + list1.get(i));



How can I change above imperative style code into declarative one ?



list2 should be [1, 3, 6, 10]






java java-8 java-stream






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 20 at 16:38









Stefan Zobel

2,51031931




2,51031931










asked Mar 20 at 16:32









run_time_errorrun_time_error

171213




171213







  • 11





    You'll notice from the answers that any solution using streams is going to be inefficient. Streams aren't really intended for this use case. (In general, streams aren't intended to replace all imperative code.)

    – Louis Wasserman
    Mar 20 at 16:48











  • @LouisWasserman I agree. But in this case I do not care about efficiency (probably should have mentioned it in the question). I wanted to write the same thing with something other than above mentioned imperative style. I could not do it myself, as I was stuck because the solution is kind of mixture of map and reduce operation

    – run_time_error
    Mar 20 at 17:17











  • Man, the lack of tuples really hurts here.

    – Alexander
    Mar 20 at 22:19






  • 2





    An extremely similar question was asked yesterday: stackoverflow.com/questions/55230261/…

    – Jacob G.
    Mar 21 at 0:41












  • 11





    You'll notice from the answers that any solution using streams is going to be inefficient. Streams aren't really intended for this use case. (In general, streams aren't intended to replace all imperative code.)

    – Louis Wasserman
    Mar 20 at 16:48











  • @LouisWasserman I agree. But in this case I do not care about efficiency (probably should have mentioned it in the question). I wanted to write the same thing with something other than above mentioned imperative style. I could not do it myself, as I was stuck because the solution is kind of mixture of map and reduce operation

    – run_time_error
    Mar 20 at 17:17











  • Man, the lack of tuples really hurts here.

    – Alexander
    Mar 20 at 22:19






  • 2





    An extremely similar question was asked yesterday: stackoverflow.com/questions/55230261/…

    – Jacob G.
    Mar 21 at 0:41







11




11





You'll notice from the answers that any solution using streams is going to be inefficient. Streams aren't really intended for this use case. (In general, streams aren't intended to replace all imperative code.)

– Louis Wasserman
Mar 20 at 16:48





You'll notice from the answers that any solution using streams is going to be inefficient. Streams aren't really intended for this use case. (In general, streams aren't intended to replace all imperative code.)

– Louis Wasserman
Mar 20 at 16:48













@LouisWasserman I agree. But in this case I do not care about efficiency (probably should have mentioned it in the question). I wanted to write the same thing with something other than above mentioned imperative style. I could not do it myself, as I was stuck because the solution is kind of mixture of map and reduce operation

– run_time_error
Mar 20 at 17:17





@LouisWasserman I agree. But in this case I do not care about efficiency (probably should have mentioned it in the question). I wanted to write the same thing with something other than above mentioned imperative style. I could not do it myself, as I was stuck because the solution is kind of mixture of map and reduce operation

– run_time_error
Mar 20 at 17:17













Man, the lack of tuples really hurts here.

– Alexander
Mar 20 at 22:19





Man, the lack of tuples really hurts here.

– Alexander
Mar 20 at 22:19




2




2





An extremely similar question was asked yesterday: stackoverflow.com/questions/55230261/…

– Jacob G.
Mar 21 at 0:41





An extremely similar question was asked yesterday: stackoverflow.com/questions/55230261/…

– Jacob G.
Mar 21 at 0:41












5 Answers
5






active

oldest

votes


















9














Streams are not suited for this kind of task, as there is state involved (the cumulative partial sum). Instead, you could use Arrays.parallelPrefix:



Integer[] arr = list1.toArray(Integer[]::new);

Arrays.parallelPrefix(arr, Integer::sum);

List<Integer> list2 = Arrays.asList(arr);


This first copies list1 to an array by using Collection.toArray, which is available since JDK 11. If you are not on Java 11 yet, you could replace the first line with the traditional toArray call:



Integer[] arr = list1.toArray(new Integer[0]);


This solution doesn't use streams, yet it's declarative, because Arrays.parallelPrefix receives the cumulative operation as an argument (Integer::sum in this case).



Time complexity is O(N), though there might be some non-minor constant costs involved associated with setting up the infrastructure needed for parallel processing. However, according to the docs:




Parallel prefix computation is usually more efficient than sequential loops for large arrays




So it seems it's worth giving this approach a try.



Also, it's worth mentioning that this approach works because Integer::sum is an associative operation. This is a requirement.






share|improve this answer




















  • 1





    Never heard of parallel prefix. thank you very much for teaching me a new concept. :). I will definitely give a try.

    – run_time_error
    Mar 20 at 17:26






  • 2





    @run_time_error Here's more reading about the subject.

    – Federico Peralta Schaffner
    Mar 20 at 18:26






  • 2





    Don’t make your life unnecessary hard. Use list1.toArray(new Integer[0]). As elaborated in this great article, using a zero size is even more efficient in the commonly used Hotspot JVM. That’s one of the reasons why JDK 11’s new method just does the same: “The default implementation calls the generator function with zero and then passes the resulting array to toArray(T[]).

    – Holger
    Mar 21 at 7:47






  • 2





    @run_time_error also worth reading: How does newly introduced Arrays.parallelPrefix(…) in Java 8 work?

    – Holger
    Mar 21 at 7:56


















5














For every index: iterate from zero to that index, get each element, and get the sum

Box the ints to Integers

Collect to a list



IntStream.range(0, list1.size())
.map(i -> IntStream.rangeClosed(0, i).map(list1::get).sum())
.boxed()
.collect(Collectors.toList());


You're adding every number together every time, rather than reusing the previous cumulative result, but streams do not lend themselves to looking at results from previous iterations.



You could write your own collector but at this point, honestly why are you even bothering with streams?



list1.stream()
.collect(
Collector.of(
ArrayList::new,
(a, b) -> a.add(a.isEmpty() ? b : b + a.get(a.size() - 1)),
(a, b) -> throw new UnsupportedOperationException();
)
);





share|improve this answer




















  • 5





    That's O(n^2) !! (as opposed to the O(n) of the OP)

    – DodgyCodeException
    Mar 20 at 16:42







  • 1





    @DodgyCodeException Yes.

    – Michael
    Mar 20 at 16:44











  • @Michael thanks for your elaborate response. I have learnt that I can write my own collector. I know this is overkill. But good to know that there are other ways.

    – run_time_error
    Mar 20 at 17:24


















3














You can use sublist to sum up until the current index from start:



List<Integer> list = IntStream.range(0, list1.size())
.mapToObj(i -> list1.subList(0, i + 1).stream().mapToInt(Integer::intValue).sum())
.collect(Collectors.toList());





share|improve this answer
































    2














    An O(n) (works only sequentially) solution would be the following, but I don't find it very elegant. I guess it is a matter of taste



    AtomicInteger ai = new AtomicInteger();
    List<Integer> collect = list1.stream()
    .map(ai::addAndGet)
    .collect(Collectors.toList());
    System.out.println(collect); // [1, 3, 6, 10]





    share|improve this answer




















    • 7





      This solution only works as long as the stream is sequential. Parallelising it would break this completely.

      – Ben R.
      Mar 20 at 17:30











    • @ben In parallel stream you couldn't have cumulative sum right?

      – Venkataraghavan Yanamandram
      Mar 21 at 8:40











    • Ruslan's answer allows for parallel streaming. The only stateful operation is over the original list itself, which we can probably assume with relative safety is read-only. Each item in the list in his solution could query over the list independently of the other stream elements.

      – Ben R.
      Mar 21 at 9:21











    • @VenkataraghavanYanamandram with other solutions yes, but they are O(n^2)

      – Yassin Hajaj
      Mar 21 at 9:22


















    1














    You can just use Stream.collect() for that:



    List<Integer> list1 = Arrays.asList(1, 2, 3, 4);
    List<Integer> list2 = list1.stream()
    .collect(ArrayList::new, (sums, number) ->
    if (sums.isEmpty())
    sums.add(number);
    else
    sums.add(sums.get(sums.size() - 1) + number);

    , (sums1, sums2) ->
    if (!sums1.isEmpty())
    int sum = sums1.get(sums1.size() - 1);
    sums2.replaceAll(num -> sum + num);

    sums1.addAll(sums2);
    );


    This solution also works for parallel streams. Use list1.parallelStream() or list1.stream().parallel() instead of list1.stream().



    The result in both cases is: [1, 3, 6, 10]






    share|improve this answer

























      Your Answer






      StackExchange.ifUsing("editor", function ()
      StackExchange.using("externalEditor", function ()
      StackExchange.using("snippets", function ()
      StackExchange.snippets.init();
      );
      );
      , "code-snippets");

      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "1"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













      draft saved

      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55265797%2fcumulative-sum-using-java-8-stream-api%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      5 Answers
      5






      active

      oldest

      votes








      5 Answers
      5






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      9














      Streams are not suited for this kind of task, as there is state involved (the cumulative partial sum). Instead, you could use Arrays.parallelPrefix:



      Integer[] arr = list1.toArray(Integer[]::new);

      Arrays.parallelPrefix(arr, Integer::sum);

      List<Integer> list2 = Arrays.asList(arr);


      This first copies list1 to an array by using Collection.toArray, which is available since JDK 11. If you are not on Java 11 yet, you could replace the first line with the traditional toArray call:



      Integer[] arr = list1.toArray(new Integer[0]);


      This solution doesn't use streams, yet it's declarative, because Arrays.parallelPrefix receives the cumulative operation as an argument (Integer::sum in this case).



      Time complexity is O(N), though there might be some non-minor constant costs involved associated with setting up the infrastructure needed for parallel processing. However, according to the docs:




      Parallel prefix computation is usually more efficient than sequential loops for large arrays




      So it seems it's worth giving this approach a try.



      Also, it's worth mentioning that this approach works because Integer::sum is an associative operation. This is a requirement.






      share|improve this answer




















      • 1





        Never heard of parallel prefix. thank you very much for teaching me a new concept. :). I will definitely give a try.

        – run_time_error
        Mar 20 at 17:26






      • 2





        @run_time_error Here's more reading about the subject.

        – Federico Peralta Schaffner
        Mar 20 at 18:26






      • 2





        Don’t make your life unnecessary hard. Use list1.toArray(new Integer[0]). As elaborated in this great article, using a zero size is even more efficient in the commonly used Hotspot JVM. That’s one of the reasons why JDK 11’s new method just does the same: “The default implementation calls the generator function with zero and then passes the resulting array to toArray(T[]).

        – Holger
        Mar 21 at 7:47






      • 2





        @run_time_error also worth reading: How does newly introduced Arrays.parallelPrefix(…) in Java 8 work?

        – Holger
        Mar 21 at 7:56















      9














      Streams are not suited for this kind of task, as there is state involved (the cumulative partial sum). Instead, you could use Arrays.parallelPrefix:



      Integer[] arr = list1.toArray(Integer[]::new);

      Arrays.parallelPrefix(arr, Integer::sum);

      List<Integer> list2 = Arrays.asList(arr);


      This first copies list1 to an array by using Collection.toArray, which is available since JDK 11. If you are not on Java 11 yet, you could replace the first line with the traditional toArray call:



      Integer[] arr = list1.toArray(new Integer[0]);


      This solution doesn't use streams, yet it's declarative, because Arrays.parallelPrefix receives the cumulative operation as an argument (Integer::sum in this case).



      Time complexity is O(N), though there might be some non-minor constant costs involved associated with setting up the infrastructure needed for parallel processing. However, according to the docs:




      Parallel prefix computation is usually more efficient than sequential loops for large arrays




      So it seems it's worth giving this approach a try.



      Also, it's worth mentioning that this approach works because Integer::sum is an associative operation. This is a requirement.






      share|improve this answer




















      • 1





        Never heard of parallel prefix. thank you very much for teaching me a new concept. :). I will definitely give a try.

        – run_time_error
        Mar 20 at 17:26






      • 2





        @run_time_error Here's more reading about the subject.

        – Federico Peralta Schaffner
        Mar 20 at 18:26






      • 2





        Don’t make your life unnecessary hard. Use list1.toArray(new Integer[0]). As elaborated in this great article, using a zero size is even more efficient in the commonly used Hotspot JVM. That’s one of the reasons why JDK 11’s new method just does the same: “The default implementation calls the generator function with zero and then passes the resulting array to toArray(T[]).

        – Holger
        Mar 21 at 7:47






      • 2





        @run_time_error also worth reading: How does newly introduced Arrays.parallelPrefix(…) in Java 8 work?

        – Holger
        Mar 21 at 7:56













      9












      9








      9







      Streams are not suited for this kind of task, as there is state involved (the cumulative partial sum). Instead, you could use Arrays.parallelPrefix:



      Integer[] arr = list1.toArray(Integer[]::new);

      Arrays.parallelPrefix(arr, Integer::sum);

      List<Integer> list2 = Arrays.asList(arr);


      This first copies list1 to an array by using Collection.toArray, which is available since JDK 11. If you are not on Java 11 yet, you could replace the first line with the traditional toArray call:



      Integer[] arr = list1.toArray(new Integer[0]);


      This solution doesn't use streams, yet it's declarative, because Arrays.parallelPrefix receives the cumulative operation as an argument (Integer::sum in this case).



      Time complexity is O(N), though there might be some non-minor constant costs involved associated with setting up the infrastructure needed for parallel processing. However, according to the docs:




      Parallel prefix computation is usually more efficient than sequential loops for large arrays




      So it seems it's worth giving this approach a try.



      Also, it's worth mentioning that this approach works because Integer::sum is an associative operation. This is a requirement.






      share|improve this answer















      Streams are not suited for this kind of task, as there is state involved (the cumulative partial sum). Instead, you could use Arrays.parallelPrefix:



      Integer[] arr = list1.toArray(Integer[]::new);

      Arrays.parallelPrefix(arr, Integer::sum);

      List<Integer> list2 = Arrays.asList(arr);


      This first copies list1 to an array by using Collection.toArray, which is available since JDK 11. If you are not on Java 11 yet, you could replace the first line with the traditional toArray call:



      Integer[] arr = list1.toArray(new Integer[0]);


      This solution doesn't use streams, yet it's declarative, because Arrays.parallelPrefix receives the cumulative operation as an argument (Integer::sum in this case).



      Time complexity is O(N), though there might be some non-minor constant costs involved associated with setting up the infrastructure needed for parallel processing. However, according to the docs:




      Parallel prefix computation is usually more efficient than sequential loops for large arrays




      So it seems it's worth giving this approach a try.



      Also, it's worth mentioning that this approach works because Integer::sum is an associative operation. This is a requirement.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Mar 25 at 15:08

























      answered Mar 20 at 16:54









      Federico Peralta SchaffnerFederico Peralta Schaffner

      23.9k43780




      23.9k43780







      • 1





        Never heard of parallel prefix. thank you very much for teaching me a new concept. :). I will definitely give a try.

        – run_time_error
        Mar 20 at 17:26






      • 2





        @run_time_error Here's more reading about the subject.

        – Federico Peralta Schaffner
        Mar 20 at 18:26






      • 2





        Don’t make your life unnecessary hard. Use list1.toArray(new Integer[0]). As elaborated in this great article, using a zero size is even more efficient in the commonly used Hotspot JVM. That’s one of the reasons why JDK 11’s new method just does the same: “The default implementation calls the generator function with zero and then passes the resulting array to toArray(T[]).

        – Holger
        Mar 21 at 7:47






      • 2





        @run_time_error also worth reading: How does newly introduced Arrays.parallelPrefix(…) in Java 8 work?

        – Holger
        Mar 21 at 7:56












      • 1





        Never heard of parallel prefix. thank you very much for teaching me a new concept. :). I will definitely give a try.

        – run_time_error
        Mar 20 at 17:26






      • 2





        @run_time_error Here's more reading about the subject.

        – Federico Peralta Schaffner
        Mar 20 at 18:26






      • 2





        Don’t make your life unnecessary hard. Use list1.toArray(new Integer[0]). As elaborated in this great article, using a zero size is even more efficient in the commonly used Hotspot JVM. That’s one of the reasons why JDK 11’s new method just does the same: “The default implementation calls the generator function with zero and then passes the resulting array to toArray(T[]).

        – Holger
        Mar 21 at 7:47






      • 2





        @run_time_error also worth reading: How does newly introduced Arrays.parallelPrefix(…) in Java 8 work?

        – Holger
        Mar 21 at 7:56







      1




      1





      Never heard of parallel prefix. thank you very much for teaching me a new concept. :). I will definitely give a try.

      – run_time_error
      Mar 20 at 17:26





      Never heard of parallel prefix. thank you very much for teaching me a new concept. :). I will definitely give a try.

      – run_time_error
      Mar 20 at 17:26




      2




      2





      @run_time_error Here's more reading about the subject.

      – Federico Peralta Schaffner
      Mar 20 at 18:26





      @run_time_error Here's more reading about the subject.

      – Federico Peralta Schaffner
      Mar 20 at 18:26




      2




      2





      Don’t make your life unnecessary hard. Use list1.toArray(new Integer[0]). As elaborated in this great article, using a zero size is even more efficient in the commonly used Hotspot JVM. That’s one of the reasons why JDK 11’s new method just does the same: “The default implementation calls the generator function with zero and then passes the resulting array to toArray(T[]).

      – Holger
      Mar 21 at 7:47





      Don’t make your life unnecessary hard. Use list1.toArray(new Integer[0]). As elaborated in this great article, using a zero size is even more efficient in the commonly used Hotspot JVM. That’s one of the reasons why JDK 11’s new method just does the same: “The default implementation calls the generator function with zero and then passes the resulting array to toArray(T[]).

      – Holger
      Mar 21 at 7:47




      2




      2





      @run_time_error also worth reading: How does newly introduced Arrays.parallelPrefix(…) in Java 8 work?

      – Holger
      Mar 21 at 7:56





      @run_time_error also worth reading: How does newly introduced Arrays.parallelPrefix(…) in Java 8 work?

      – Holger
      Mar 21 at 7:56













      5














      For every index: iterate from zero to that index, get each element, and get the sum

      Box the ints to Integers

      Collect to a list



      IntStream.range(0, list1.size())
      .map(i -> IntStream.rangeClosed(0, i).map(list1::get).sum())
      .boxed()
      .collect(Collectors.toList());


      You're adding every number together every time, rather than reusing the previous cumulative result, but streams do not lend themselves to looking at results from previous iterations.



      You could write your own collector but at this point, honestly why are you even bothering with streams?



      list1.stream()
      .collect(
      Collector.of(
      ArrayList::new,
      (a, b) -> a.add(a.isEmpty() ? b : b + a.get(a.size() - 1)),
      (a, b) -> throw new UnsupportedOperationException();
      )
      );





      share|improve this answer




















      • 5





        That's O(n^2) !! (as opposed to the O(n) of the OP)

        – DodgyCodeException
        Mar 20 at 16:42







      • 1





        @DodgyCodeException Yes.

        – Michael
        Mar 20 at 16:44











      • @Michael thanks for your elaborate response. I have learnt that I can write my own collector. I know this is overkill. But good to know that there are other ways.

        – run_time_error
        Mar 20 at 17:24















      5














      For every index: iterate from zero to that index, get each element, and get the sum

      Box the ints to Integers

      Collect to a list



      IntStream.range(0, list1.size())
      .map(i -> IntStream.rangeClosed(0, i).map(list1::get).sum())
      .boxed()
      .collect(Collectors.toList());


      You're adding every number together every time, rather than reusing the previous cumulative result, but streams do not lend themselves to looking at results from previous iterations.



      You could write your own collector but at this point, honestly why are you even bothering with streams?



      list1.stream()
      .collect(
      Collector.of(
      ArrayList::new,
      (a, b) -> a.add(a.isEmpty() ? b : b + a.get(a.size() - 1)),
      (a, b) -> throw new UnsupportedOperationException();
      )
      );





      share|improve this answer




















      • 5





        That's O(n^2) !! (as opposed to the O(n) of the OP)

        – DodgyCodeException
        Mar 20 at 16:42







      • 1





        @DodgyCodeException Yes.

        – Michael
        Mar 20 at 16:44











      • @Michael thanks for your elaborate response. I have learnt that I can write my own collector. I know this is overkill. But good to know that there are other ways.

        – run_time_error
        Mar 20 at 17:24













      5












      5








      5







      For every index: iterate from zero to that index, get each element, and get the sum

      Box the ints to Integers

      Collect to a list



      IntStream.range(0, list1.size())
      .map(i -> IntStream.rangeClosed(0, i).map(list1::get).sum())
      .boxed()
      .collect(Collectors.toList());


      You're adding every number together every time, rather than reusing the previous cumulative result, but streams do not lend themselves to looking at results from previous iterations.



      You could write your own collector but at this point, honestly why are you even bothering with streams?



      list1.stream()
      .collect(
      Collector.of(
      ArrayList::new,
      (a, b) -> a.add(a.isEmpty() ? b : b + a.get(a.size() - 1)),
      (a, b) -> throw new UnsupportedOperationException();
      )
      );





      share|improve this answer















      For every index: iterate from zero to that index, get each element, and get the sum

      Box the ints to Integers

      Collect to a list



      IntStream.range(0, list1.size())
      .map(i -> IntStream.rangeClosed(0, i).map(list1::get).sum())
      .boxed()
      .collect(Collectors.toList());


      You're adding every number together every time, rather than reusing the previous cumulative result, but streams do not lend themselves to looking at results from previous iterations.



      You could write your own collector but at this point, honestly why are you even bothering with streams?



      list1.stream()
      .collect(
      Collector.of(
      ArrayList::new,
      (a, b) -> a.add(a.isEmpty() ? b : b + a.get(a.size() - 1)),
      (a, b) -> throw new UnsupportedOperationException();
      )
      );






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Mar 20 at 16:55

























      answered Mar 20 at 16:41









      MichaelMichael

      22.3k83774




      22.3k83774







      • 5





        That's O(n^2) !! (as opposed to the O(n) of the OP)

        – DodgyCodeException
        Mar 20 at 16:42







      • 1





        @DodgyCodeException Yes.

        – Michael
        Mar 20 at 16:44











      • @Michael thanks for your elaborate response. I have learnt that I can write my own collector. I know this is overkill. But good to know that there are other ways.

        – run_time_error
        Mar 20 at 17:24












      • 5





        That's O(n^2) !! (as opposed to the O(n) of the OP)

        – DodgyCodeException
        Mar 20 at 16:42







      • 1





        @DodgyCodeException Yes.

        – Michael
        Mar 20 at 16:44











      • @Michael thanks for your elaborate response. I have learnt that I can write my own collector. I know this is overkill. But good to know that there are other ways.

        – run_time_error
        Mar 20 at 17:24







      5




      5





      That's O(n^2) !! (as opposed to the O(n) of the OP)

      – DodgyCodeException
      Mar 20 at 16:42






      That's O(n^2) !! (as opposed to the O(n) of the OP)

      – DodgyCodeException
      Mar 20 at 16:42





      1




      1





      @DodgyCodeException Yes.

      – Michael
      Mar 20 at 16:44





      @DodgyCodeException Yes.

      – Michael
      Mar 20 at 16:44













      @Michael thanks for your elaborate response. I have learnt that I can write my own collector. I know this is overkill. But good to know that there are other ways.

      – run_time_error
      Mar 20 at 17:24





      @Michael thanks for your elaborate response. I have learnt that I can write my own collector. I know this is overkill. But good to know that there are other ways.

      – run_time_error
      Mar 20 at 17:24











      3














      You can use sublist to sum up until the current index from start:



      List<Integer> list = IntStream.range(0, list1.size())
      .mapToObj(i -> list1.subList(0, i + 1).stream().mapToInt(Integer::intValue).sum())
      .collect(Collectors.toList());





      share|improve this answer





























        3














        You can use sublist to sum up until the current index from start:



        List<Integer> list = IntStream.range(0, list1.size())
        .mapToObj(i -> list1.subList(0, i + 1).stream().mapToInt(Integer::intValue).sum())
        .collect(Collectors.toList());





        share|improve this answer



























          3












          3








          3







          You can use sublist to sum up until the current index from start:



          List<Integer> list = IntStream.range(0, list1.size())
          .mapToObj(i -> list1.subList(0, i + 1).stream().mapToInt(Integer::intValue).sum())
          .collect(Collectors.toList());





          share|improve this answer















          You can use sublist to sum up until the current index from start:



          List<Integer> list = IntStream.range(0, list1.size())
          .mapToObj(i -> list1.subList(0, i + 1).stream().mapToInt(Integer::intValue).sum())
          .collect(Collectors.toList());






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Mar 20 at 16:44

























          answered Mar 20 at 16:43









          RuslanRuslan

          4,73811230




          4,73811230





















              2














              An O(n) (works only sequentially) solution would be the following, but I don't find it very elegant. I guess it is a matter of taste



              AtomicInteger ai = new AtomicInteger();
              List<Integer> collect = list1.stream()
              .map(ai::addAndGet)
              .collect(Collectors.toList());
              System.out.println(collect); // [1, 3, 6, 10]





              share|improve this answer




















              • 7





                This solution only works as long as the stream is sequential. Parallelising it would break this completely.

                – Ben R.
                Mar 20 at 17:30











              • @ben In parallel stream you couldn't have cumulative sum right?

                – Venkataraghavan Yanamandram
                Mar 21 at 8:40











              • Ruslan's answer allows for parallel streaming. The only stateful operation is over the original list itself, which we can probably assume with relative safety is read-only. Each item in the list in his solution could query over the list independently of the other stream elements.

                – Ben R.
                Mar 21 at 9:21











              • @VenkataraghavanYanamandram with other solutions yes, but they are O(n^2)

                – Yassin Hajaj
                Mar 21 at 9:22















              2














              An O(n) (works only sequentially) solution would be the following, but I don't find it very elegant. I guess it is a matter of taste



              AtomicInteger ai = new AtomicInteger();
              List<Integer> collect = list1.stream()
              .map(ai::addAndGet)
              .collect(Collectors.toList());
              System.out.println(collect); // [1, 3, 6, 10]





              share|improve this answer




















              • 7





                This solution only works as long as the stream is sequential. Parallelising it would break this completely.

                – Ben R.
                Mar 20 at 17:30











              • @ben In parallel stream you couldn't have cumulative sum right?

                – Venkataraghavan Yanamandram
                Mar 21 at 8:40











              • Ruslan's answer allows for parallel streaming. The only stateful operation is over the original list itself, which we can probably assume with relative safety is read-only. Each item in the list in his solution could query over the list independently of the other stream elements.

                – Ben R.
                Mar 21 at 9:21











              • @VenkataraghavanYanamandram with other solutions yes, but they are O(n^2)

                – Yassin Hajaj
                Mar 21 at 9:22













              2












              2








              2







              An O(n) (works only sequentially) solution would be the following, but I don't find it very elegant. I guess it is a matter of taste



              AtomicInteger ai = new AtomicInteger();
              List<Integer> collect = list1.stream()
              .map(ai::addAndGet)
              .collect(Collectors.toList());
              System.out.println(collect); // [1, 3, 6, 10]





              share|improve this answer















              An O(n) (works only sequentially) solution would be the following, but I don't find it very elegant. I guess it is a matter of taste



              AtomicInteger ai = new AtomicInteger();
              List<Integer> collect = list1.stream()
              .map(ai::addAndGet)
              .collect(Collectors.toList());
              System.out.println(collect); // [1, 3, 6, 10]






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Mar 21 at 9:27

























              answered Mar 20 at 16:49









              Yassin HajajYassin Hajaj

              14.6k73062




              14.6k73062







              • 7





                This solution only works as long as the stream is sequential. Parallelising it would break this completely.

                – Ben R.
                Mar 20 at 17:30











              • @ben In parallel stream you couldn't have cumulative sum right?

                – Venkataraghavan Yanamandram
                Mar 21 at 8:40











              • Ruslan's answer allows for parallel streaming. The only stateful operation is over the original list itself, which we can probably assume with relative safety is read-only. Each item in the list in his solution could query over the list independently of the other stream elements.

                – Ben R.
                Mar 21 at 9:21











              • @VenkataraghavanYanamandram with other solutions yes, but they are O(n^2)

                – Yassin Hajaj
                Mar 21 at 9:22












              • 7





                This solution only works as long as the stream is sequential. Parallelising it would break this completely.

                – Ben R.
                Mar 20 at 17:30











              • @ben In parallel stream you couldn't have cumulative sum right?

                – Venkataraghavan Yanamandram
                Mar 21 at 8:40











              • Ruslan's answer allows for parallel streaming. The only stateful operation is over the original list itself, which we can probably assume with relative safety is read-only. Each item in the list in his solution could query over the list independently of the other stream elements.

                – Ben R.
                Mar 21 at 9:21











              • @VenkataraghavanYanamandram with other solutions yes, but they are O(n^2)

                – Yassin Hajaj
                Mar 21 at 9:22







              7




              7





              This solution only works as long as the stream is sequential. Parallelising it would break this completely.

              – Ben R.
              Mar 20 at 17:30





              This solution only works as long as the stream is sequential. Parallelising it would break this completely.

              – Ben R.
              Mar 20 at 17:30













              @ben In parallel stream you couldn't have cumulative sum right?

              – Venkataraghavan Yanamandram
              Mar 21 at 8:40





              @ben In parallel stream you couldn't have cumulative sum right?

              – Venkataraghavan Yanamandram
              Mar 21 at 8:40













              Ruslan's answer allows for parallel streaming. The only stateful operation is over the original list itself, which we can probably assume with relative safety is read-only. Each item in the list in his solution could query over the list independently of the other stream elements.

              – Ben R.
              Mar 21 at 9:21





              Ruslan's answer allows for parallel streaming. The only stateful operation is over the original list itself, which we can probably assume with relative safety is read-only. Each item in the list in his solution could query over the list independently of the other stream elements.

              – Ben R.
              Mar 21 at 9:21













              @VenkataraghavanYanamandram with other solutions yes, but they are O(n^2)

              – Yassin Hajaj
              Mar 21 at 9:22





              @VenkataraghavanYanamandram with other solutions yes, but they are O(n^2)

              – Yassin Hajaj
              Mar 21 at 9:22











              1














              You can just use Stream.collect() for that:



              List<Integer> list1 = Arrays.asList(1, 2, 3, 4);
              List<Integer> list2 = list1.stream()
              .collect(ArrayList::new, (sums, number) ->
              if (sums.isEmpty())
              sums.add(number);
              else
              sums.add(sums.get(sums.size() - 1) + number);

              , (sums1, sums2) ->
              if (!sums1.isEmpty())
              int sum = sums1.get(sums1.size() - 1);
              sums2.replaceAll(num -> sum + num);

              sums1.addAll(sums2);
              );


              This solution also works for parallel streams. Use list1.parallelStream() or list1.stream().parallel() instead of list1.stream().



              The result in both cases is: [1, 3, 6, 10]






              share|improve this answer





























                1














                You can just use Stream.collect() for that:



                List<Integer> list1 = Arrays.asList(1, 2, 3, 4);
                List<Integer> list2 = list1.stream()
                .collect(ArrayList::new, (sums, number) ->
                if (sums.isEmpty())
                sums.add(number);
                else
                sums.add(sums.get(sums.size() - 1) + number);

                , (sums1, sums2) ->
                if (!sums1.isEmpty())
                int sum = sums1.get(sums1.size() - 1);
                sums2.replaceAll(num -> sum + num);

                sums1.addAll(sums2);
                );


                This solution also works for parallel streams. Use list1.parallelStream() or list1.stream().parallel() instead of list1.stream().



                The result in both cases is: [1, 3, 6, 10]






                share|improve this answer



























                  1












                  1








                  1







                  You can just use Stream.collect() for that:



                  List<Integer> list1 = Arrays.asList(1, 2, 3, 4);
                  List<Integer> list2 = list1.stream()
                  .collect(ArrayList::new, (sums, number) ->
                  if (sums.isEmpty())
                  sums.add(number);
                  else
                  sums.add(sums.get(sums.size() - 1) + number);

                  , (sums1, sums2) ->
                  if (!sums1.isEmpty())
                  int sum = sums1.get(sums1.size() - 1);
                  sums2.replaceAll(num -> sum + num);

                  sums1.addAll(sums2);
                  );


                  This solution also works for parallel streams. Use list1.parallelStream() or list1.stream().parallel() instead of list1.stream().



                  The result in both cases is: [1, 3, 6, 10]






                  share|improve this answer















                  You can just use Stream.collect() for that:



                  List<Integer> list1 = Arrays.asList(1, 2, 3, 4);
                  List<Integer> list2 = list1.stream()
                  .collect(ArrayList::new, (sums, number) ->
                  if (sums.isEmpty())
                  sums.add(number);
                  else
                  sums.add(sums.get(sums.size() - 1) + number);

                  , (sums1, sums2) ->
                  if (!sums1.isEmpty())
                  int sum = sums1.get(sums1.size() - 1);
                  sums2.replaceAll(num -> sum + num);

                  sums1.addAll(sums2);
                  );


                  This solution also works for parallel streams. Use list1.parallelStream() or list1.stream().parallel() instead of list1.stream().



                  The result in both cases is: [1, 3, 6, 10]







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Mar 20 at 18:12

























                  answered Mar 20 at 17:54









                  Samuel PhilippSamuel Philipp

                  4,30021530




                  4,30021530



























                      draft saved

                      draft discarded
















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55265797%2fcumulative-sum-using-java-8-stream-api%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Masuk log Menu navigasi

                      Identifying “long and narrow” polygons in with PostGISlength and width of polygonWhy postgis st_overlaps reports Qgis' “avoid intersections” generated polygon as overlapping with others?Adjusting polygons to boundary and filling holesDrawing polygons with fixed area?How to remove spikes in Polygons with PostGISDeleting sliver polygons after difference operation in QGIS?Snapping boundaries in PostGISSplit polygon into parts adding attributes based on underlying polygon in QGISSplitting overlap between polygons and assign to nearest polygon using PostGIS?Expanding polygons and clipping at midpoint?Removing Intersection of Buffers in Same Layers

                      Старые Смолеговицы Содержание История | География | Демография | Достопримечательности | Примечания | НавигацияHGЯOLHGЯOL41 206 832 01641 606 406 141Административно-территориальное деление Ленинградской области«Переписная оброчная книга Водской пятины 1500 года», С. 793«Карта Ингерманландии: Ивангорода, Яма, Копорья, Нотеборга», по материалам 1676 г.«Генеральная карта провинции Ингерманландии» Э. Белинга и А. Андерсина, 1704 г., составлена по материалам 1678 г.«Географический чертёж над Ижорскою землей со своими городами» Адриана Шонбека 1705 г.Новая и достоверная всей Ингерманландии ланткарта. Грав. А. Ростовцев. СПб., 1727 г.Топографическая карта Санкт-Петербургской губернии. 5-и верстка. Шуберт. 1834 г.Описание Санкт-Петербургской губернии по уездам и станамСпецкарта западной части России Ф. Ф. Шуберта. 1844 г.Алфавитный список селений по уездам и станам С.-Петербургской губернииСписки населённых мест Российской Империи, составленные и издаваемые центральным статистическим комитетом министерства внутренних дел. XXXVII. Санкт-Петербургская губерния. По состоянию на 1862 год. СПб. 1864. С. 203Материалы по статистике народного хозяйства в С.-Петербургской губернии. Вып. IX. Частновладельческое хозяйство в Ямбургском уезде. СПб, 1888, С. 146, С. 2, 7, 54Положение о гербе муниципального образования Курское сельское поселениеСправочник истории административно-территориального деления Ленинградской области.Топографическая карта Ленинградской области, квадрат О-35-23-В (Хотыницы), 1930 г.АрхивированоАдминистративно-территориальное деление Ленинградской области. — Л., 1933, С. 27, 198АрхивированоАдминистративно-экономический справочник по Ленинградской области. — Л., 1936, с. 219АрхивированоАдминистративно-территориальное деление Ленинградской области. — Л., 1966, с. 175АрхивированоАдминистративно-территориальное деление Ленинградской области. — Лениздат, 1973, С. 180АрхивированоАдминистративно-территориальное деление Ленинградской области. — Лениздат, 1990, ISBN 5-289-00612-5, С. 38АрхивированоАдминистративно-территориальное деление Ленинградской области. — СПб., 2007, с. 60АрхивированоКоряков Юрий База данных «Этно-языковой состав населённых пунктов России». Ленинградская область.Административно-территориальное деление Ленинградской области. — СПб, 1997, ISBN 5-86153-055-6, С. 41АрхивированоКультовый комплекс Старые Смолеговицы // Электронная энциклопедия ЭрмитажаПроблемы выявления, изучения и сохранения культовых комплексов с каменными крестами: по материалам работ 2016-2017 гг. в Ленинградской области