title: How to perform an outer join on two or more Streams
body: <p>In my application I use several Streams that provide Elements of the form ( ID, value ). An Element is defined by the following class:</p>
  
  <pre><code>static final class Element&lt;T&gt; implements Comparable&lt;Element&lt;T&gt;&gt; {
      final long id;
      final T value;
  
      Element(int id, T value) {
          this.id = id;
          this.value = value;
      }
  
      @Override
      public int compareTo(Element o) {
          return Long.compare(id, o.id);
      }
  }
  </code></pre>
  
  <p>My goal is to join two or more Streams by the Element's IDs (in each stream, the IDs are sorted and strictly monotonic), e.g.:</p>
  
  <pre><code>    Stream &lt;Element&gt; colour = Arrays.stream(new Element[]{new Element(1, "red"), new Element(2, "green"), new Element(4, "red"), new Element(6, "blue")}); 
      Stream &lt;Element&gt; length = Arrays.stream(new Element[]{new Element(2, 28), new Element(3, 9), new Element(4, 17), new Element(6, 11)});
      Stream &lt;Element&gt; mass = Arrays.stream(new Element[]{new Element(1, 87.9f), new Element(2, 21.0f), new Element(3, 107f)});
  </code></pre>
  
  <p>into a single Stream that contains Elements of the form ( ID, [T1, T2, T3] ):</p>
  
  <pre><code>    Stream&lt;Element&lt;Object[]&gt;&gt; allProps = joinStreams(colour, length, mass);
  </code></pre>
  
  <p>by applying some method like this:</p>
  
  <pre><code>public Stream&lt;Element&lt;Object[]&gt;&gt; joinStreams(Stream&lt;Element&gt;... streams) {
      return ...;
  }
  </code></pre>
  
  <p>The resulting Stream should deliver a FULL OUTER JOIN, i.e. for the above example:</p>
  
  <pre><code>1, "red",   null, 87.9
  2, "green", 28,   21.0
  3, null,    9,    107
  4, "red"    17,   null
  6, "blue",  11,   null
  </code></pre>
  
  <p>Since my experience with Java's streaming API is quite basic so far I normally use iterators for such tasks.</p>
  
  <p>Is there an idiomatic (and efficient) way to perfom this kind of join with Streams? Are there any utility libraries that I could use?</p>
  
  <p>Side note: The example is simplified. The application receives the data from something like a column-oriented data store (no real DMBS), that is several gigabytes in size and does not fit easily into memory. There's also no built-in support for this kind of join operation.</p>