title: "Partly" reducing a Stream
body: <p>Given the following context:</p>
  <pre><code>public interface IAdditive&lt;T&gt; {
      /** True if still capable to crunch. */
      boolean canCrunch();
      /** True if capable to crunch with B. */
      boolean canCrunch(T other);
      /** Returns a new T which is the sum of this and other */
      T crunch(T other);    
  }
  </code></pre>
  <h1></h1>
  <pre><code>class A implements IAdditive&lt;A&gt; {
      ..
      A crunch(A other) {...}
  }
  </code></pre>
  <h1></h1>
  <pre><code>class B extends A {
      ...
      B crunch(B other) {...}
  }
  </code></pre>
  <h1></h1>
  <pre><code>class C implements IAdditive&lt;C&gt; {
      ...
      C crunch(C other) {...}
  }
  </code></pre>
  <p>Now I want to &quot;crunch&quot; a Stream of Implementations</p>
  <pre><code>/** Chrunches the streams where possible */
  public Stream&lt;A&gt; crunchStream(Stream s) {
      return s.map(...);
  }
  </code></pre>
  <p>I am stuck with my rather naive approach:</p>
  <pre><code>public Set&lt;A&gt; collect(Stream&lt;A&gt; stream) {
      Set&lt;I&gt; res = new HashSet&lt;&gt;();
      Set&lt;I&gt; set = stream
              .filter(IAdditive::canCrunch)
              .collect(Collectors.toSet());
      set.forEach(setItem -&gt; set.stream()
              .filter(concurrentItem -&gt; concurrentItem.canCrunch(setItem))
              .map(setItem::crunch)
              .forEach(res::add));
      return res;
  }
  </code></pre>
  <p>That should be flawed. I am unfolding the stream, add mandatory complexity,  and If I want the interface to offer that in a default method I would have to use rawtypes.</p>
  <p>I believe I could use some help :-)</p>