title: Does every stateful intermediate Stream API operation guarantee a new source collection?
body: <p>Is the following statement true?</p>
  <blockquote>
  <p>The <code>sorted()</code> operation is a “stateful intermediate operation”, which means that subsequent operations no longer operate on the backing collection, but on an internal state.</p>
  </blockquote>
  <p><sup>(<a href="https://www.toptal.com/java/top-10-most-common-java-development-mistakes" rel="nofollow noreferrer">Source</a> and <a href="https://dzone.com/articles/java-8-friday-10-subtle" rel="nofollow noreferrer">source</a> - they seem to copy from each other or come from the same source.)</sup></p>
  <p><strong>Disclaimer:</strong> I am aware the following snippets are not legit usages of Java Stream API. Don't use in the production code.</p>
  <p>I have tested <a href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#sorted--" rel="nofollow noreferrer"><code>Stream::sorted</code></a> as a snippet from sources above:</p>
  <pre><code>final List&lt;Integer&gt; list = IntStream.range(0, 10).boxed().collect(Collectors.toList());
      
  list.stream()
      .filter(i -&gt; i &gt; 5)
      .sorted()
      .forEach(list::remove);
  
  System.out.println(list);            // Prints [0, 1, 2, 3, 4, 5]
  </code></pre>
  <p>It works. I replaced <a href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#sorted--" rel="nofollow noreferrer"><code>Stream::sorted</code></a> with <a href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#distinct--" rel="nofollow noreferrer"><code>Stream::distinct</code></a>, <a href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#limit-long-" rel="nofollow noreferrer"><code>Stream::limit</code></a> and <a href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#skip-long-" rel="nofollow noreferrer"><code>Stream::skip</code></a>:</p>
  <pre><code>final List&lt;Integer&gt; list = IntStream.range(0, 10).boxed().collect(Collectors.toList());
      
  list.stream()
      .filter(i -&gt; i &gt; 5)
      .distinct()
      .forEach(list::remove);          // Throws NullPointerException
  </code></pre>
  <p>To my surprise, the <code>NullPointerException</code> is thrown.</p>
  <p>All the tested methods follow the <a href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#StreamOps" rel="nofollow noreferrer">stateful intermediate operation</a> characteristics. Yet, this unique behavior of <a href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#sorted--" rel="nofollow noreferrer"><code>Stream::sorted</code></a> is not documented nor the <a href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#StreamOps" rel="nofollow noreferrer">Stream operations and pipelines</a> part explains whether the <em>stateful intermediate operations</em> really guarantee a new source collection.</p>
  <p>Where my confusion comes from and what is the explanation of the behavior above?</p>