 <p>The solution is to use <code>Stream.collect</code>. To create a Collector using its builder pattern is already given as solution. The alternative is the other overloaded <code>collect</code> being a tiny bit more primitive.</p> <pre><code> List&lt;String&gt; strings = Arrays.asList("a", "b", null, "c", null, "d", "e"); List&lt;List&lt;String&gt;&gt; groups = strings.stream() .collect(() -&gt; { List&lt;List&lt;String&gt;&gt; list = new ArrayList&lt;&gt;(); list.add(new ArrayList&lt;&gt;()); return list; }, (list, s) -&gt; { if (s == null) { list.add(new ArrayList&lt;&gt;()); } else { list.get(list.size() - 1).add(s); } }, (list1, list2) -&gt; { // Simple merging of partial sublists would // introduce a false level-break at the beginning. list1.get(list1.size() - 1).addAll(list2.remove(0)); list1.addAll(list2); }); </code></pre> <p>As one sees, I make a list of string lists, where there always is at least one last (empty) string list.</p> <ul> <li>The first function creates a starting list of string lists. <strong>It specifies the result (typed) object.</strong></li> <li>The second function is called to process each element. <strong>It is an action on the partial result and an element.</strong></li> <li>The third is not really used, it comes into play on parallelising the processing, when partial results must be combined.</li> </ul> <hr> <p><strong><em>A solution with an accumulator:</em></strong></p> <p><em>As @StuartMarks points out, the combiner does not fullfill the contract for parallelism.</em></p> <p>Due to the comment of @ArnaudDenoyelle a version using <code>reduce</code>.</p> <pre><code> List&lt;List&lt;String&gt;&gt; groups = strings.stream() .reduce(new ArrayList&lt;List&lt;String&gt;&gt;(), (list, s) -&gt; { if (list.isEmpty()) { list.add(new ArrayList&lt;&gt;()); } if (s == null) { list.add(new ArrayList&lt;&gt;()); } else { list.get(list.size() - 1).add(s); } return list; }, (list1, list2) -&gt; { list1.addAll(list2); return list1; }); </code></pre> <ul> <li>The first parameter is the accumulated object.</li> <li>The second function accumulates.</li> <li>The third is the aforementioned combiner.</li> </ul>