ConsumingRouter to consume based on condition
There is a Map.forEach(BiConsumer) that you can use as well:

@Override
public void accept(T t) {
    map.forEach((k,v) -&gt; {
        if (k.test(t)) {
            v.accept(t);
        }
    });
}


Alternatively, you can convert that if-statement in the form of an Optional too if you can ignore null values (as commented by @Misha):

@Override
public void accept(T t) {
    // answer update: switched to Optional.of() for reasons mentioned in comments
    map.forEach((k,v) -&gt; Optional.of(t).filter(k::test).ifPresent(v));
}


You can also take a look at this StackOverflow question for some insight about splitting two Streams into two Streams... similar to yours, except that you are only concerned with multiple Consumers to terminate the source Stream.

edit: Oh yeah, you may want to consider having your sub() (subscribe?) method return the reference to itself, so that you can do method chaining as such:

router.sub(p1, c1).sub(p2, c2);


edit 2: @Misha has a good suggestion for doing away with the Map, if that suits your requirements as well.