title: Can sequential stream operations have side-effects?
body: <p>I'm trying to stream a limited number of values into a set, but I need to verify that they're new elements before applying the limit. For example:</p>
  
  <pre><code>Set&lt;Integer&gt; destination = ... 
  Set&lt;Integer&gt; source = ...
  source.stream()
          .filter(i -&gt; !destination.contains(i))
          .limit(10)
          .forEach(destination::add);
  </code></pre>
  
  <p>But the redundant <code>contains()</code> check is bothering me, since <code>add()</code> can both add the element <em>and</em> report whether it's new to the collection. So I was thinking of doing this:</p>
  
  <pre><code>source.stream()
          .filter(destination::add)
          .limit(10)
          .forEach(i -&gt; {});    // no-op terminal operation to force evaluation
  </code></pre>
  
  <p>Ignoring the hacky terminal operation, there's the problem of using a filter operation with a side-effect, which is generally discouraged. I understand why it would be unsafe to use <code>map()</code> and <code>filter()</code> with side-effects on parallel streams. My question is, would it be acceptable on a sequential stream, as in this case? If not, why not?</p>