Can intermediate stream operations be encapsulated without breaking the pipeline?
<p>With Java 8 Streams, is it possible to encapsulate and reuse intermediate stream operations in some way that won't break the stream pipeline?</p>

<p>Consider this example from the <a href="https://docs.oracle.com/javase/tutorial/collections/streams/">Java Tutorial on streams</a>:</p>

<pre><code>double average = roster
    .stream()
    .filter(p -&gt; p.getGender() == Person.Sex.MALE)
    .mapToInt(Person::getAge)
    .average()
    .getAsDouble();
</code></pre>

<p>Suppose I need to use the filter and mapToInt operations in different places throughout my code.  I might want try and to encapsulate that logic so it can be reused, for example:</p>

<pre><code>IntStream maleAges(Stream&lt;Person&gt; stream) {
    return stream
        .filter(p -&gt; p.getGender() == Person.Sex.MALE)
        .mapToInt(Person::getAge)
}
</code></pre>

<p>This is nice, but to use it I might have to make a mess of the stream pipeline.  For example, if I want the average age of men named Bob:</p>

<pre><code>double averageBob =
    maleAges(roster
        .stream()
        .filter(p -&gt; "Bob".equals(p.getName()))
    )
    .average()
    .getAsDouble();
</code></pre>

<p>Is there some better way to do it?  I'm thinking of something along these lines:</p>

<pre><code>double averageBob = roster
    .stream()
    .filter(p -&gt; "Bob".equals(p.getName()))
    .apply(this::maleAges) // Doesn't compile
    .average()
    .getAsDouble();
</code></pre>