title: Java parallel stream to fill array
body: <p>I have an hashmap that is very big and it's full of prime numbers.</p>
  
  <pre><code>var mapA = new HashMap&lt;Integer, Long&gt;();
  </code></pre>
  
  <p>I need to do heavy calculations on it and so I am using parallel streams:</p>
  
  <pre><code>var res = new ArrayList&lt;Integer();
  
  mapA.entrySet()
          .parallelStream()
          .forEach( x -&gt; {
  
              var values = mapA.entrySet()
                                      .parallelStream()
                                      .filter( /*conditions*/ )
                                      .map(y -&gt; y.getKey())
                                      .toArray();                 
  
              Arrays.stream(values)
                        .parallel()
                        .sorted()
                        .forEach(val -&gt; {
  
                             synchronized (this) {
                                  res.add(x.getKey());
                                  res.add((Integer) val);
                             }
  
                        });
  
  
          });
  </code></pre>
  
  <p>As you can see, there is <code>res</code> which is an array that is outside the scope of the stream. I need the loop to be parallel otherwise the calculation could take minutes and minutes. Is this needed?</p>
  
  <pre><code>.forEach(val -&gt; {
  
      synchronized (this) {
          res.add(x.getKey());
          res.add((Integer) val);
      }
  
  });
  </code></pre>
  
  <p>I have added the <code>synchronized</code> because since the stream runs in parallel, I don't want to have race conditions in case that 2 or more threads are adding data in <code>res</code> at the same time.</p>
  
  <p>I have tried to remove the synchronized (this) and the program still works fine. But how can I be sure that it will always work fine?</p>
  
  <p>Thank you</p>
  
  <hr>
  
  <p>I am going to add here the entire code if needed:</p>
  
  <pre><code>import java.util.*;
  import java.util.stream.Collectors;
  import java.util.stream.IntStream;
  
  public class DiffieHellman {
  
      private static final int LIMIT = 65536;
  
      private final long p;
      private final long g;
  
      public DiffieHellman(long p, long g) {
          this.p = p;
          this.g = g;
      }
  
      public List&lt;Integer&gt; tryBruteForce(long publicA, long publicB) {
          List&lt;Integer&gt; res = new ArrayList&lt;Integer&gt;();
  
          var mapA = new HashMap&lt;Integer, Long&gt;(
                  IntStream
                          .rangeClosed(0, LIMIT)
                          .parallel()
                          .boxed()
                          .collect(
                                  Collectors.toMap(x -&gt; x, x -&gt; DiffieHellmanUtils.modPow(publicB, x, p))
                          )
          );
  
          var mapB = new HashMap&lt;Integer, Long&gt;(
                  IntStream
                          .rangeClosed(0, LIMIT)
                          .parallel()
                          .boxed()
                          .collect(
                                  Collectors.toMap(x -&gt; x, x -&gt; DiffieHellmanUtils.modPow(publicB, x, p))
                          )
          );
  
          mapA.entrySet()
                      .parallelStream()
                      .forEach( x -&gt; {
  
                          var values = mapB.entrySet()
                                          .parallelStream()
                                          .filter( y -&gt; y.getValue().equals(x.getValue()))
                                          .map(Map.Entry::getKey)
                                          .toArray(Integer[]::new);
  
                          Arrays.stream(values)
                                  .parallel()
                                  .sorted()
                                  .forEach(val -&gt; {
                                          res.add(x.getKey());
                                          res.add((Integer) val);
                                  });
  
  
                      });
  
          return res;
      }
  
  }
  </code></pre>