title: How to stop parallel stream once findAny match found?
body: <p>I'm trying locate the first (any) member of a list that matches a given predicate like so:</p>
  
  <pre class="lang-java prettyprint-override"><code>Item item = items.parallelStream()
    .map(i -&gt; i.doSomethingExpensive())
    .filter(predicate)
    .findAny()
    .orElse(null);
  </code></pre>
  
  <p>I would expect that once <code>findAny()</code> gets a match, it would return immediately, but that doesn't appear to be the case. Instead it seems to wait for the map method to finish on most of the elements before returning. How can I return the first result immediately and cancel the other parallel streams? Is there a better way to do this than using streams such as <code>CompletableFuture</code>?</p>
  
  <p>Here's a simple example to show the behavior:</p>
  
  <pre class="lang-java prettyprint-override"><code>private static void log(String msg) {
      private static void log(String msg) {
      SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS");
      System.out.println(sdf.format(new Date()) + " " + msg);
  }
  
  Random random = new Random();
  List&lt;Integer&gt; nums = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14);
  Optional&lt;Integer&gt; num = nums.parallelStream()
    .map(n -&gt; {
      long delay = Math.abs(random.nextLong()) % 10000;
      log("Waiting on " + n + " for " + delay + " ms");
      try { Thread.sleep(delay); }
      catch (InterruptedException e) { System.err.println("Interruption error"); }
      return n * n;
    })
    .filter(n -&gt; n &lt; 30)
    .peek(n -&gt; log("Found match: " + n))
    .findAny();
  
  log("First match: " + num);
  </code></pre>
  
  <p>Log output: </p>
  
  <pre><code>14:52:27.061 Waiting on 9 for 2271 ms
  14:52:27.061 Waiting on 2 for 1124 ms
  14:52:27.061 Waiting on 13 for 547 ms
  14:52:27.061 Waiting on 4 for 517 ms
  14:52:27.061 Waiting on 1 for 1210 ms
  14:52:27.061 Waiting on 6 for 2646 ms
  14:52:27.061 Waiting on 0 for 4393 ms
  14:52:27.061 Waiting on 12 for 5520 ms
  14:52:27.581 Found match: 16
  14:52:27.582 Waiting on 3 for 5365 ms
  14:52:28.188 Found match: 4
  14:52:28.275 Found match: 1
  14:52:31.457 Found match: 0
  14:52:32.950 Found match: 9
  14:52:32.951 First match: Optional[0]
  </code></pre>
  
  <p>Once a match is found (in this case 16), <code>findAny()</code> does not return immediately, but instead blocks until the remaining threads finish. In this case, the caller is waiting an extra 5 seconds before returning after a match has already been found.</p>