Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I terminate a Stream if I don't need any value from termination?

I have a Stream that does all processing in peek() methods. I don't need any result from the Stream, but I need a terminal operation in order for processing to occur. Of course I can terminate the Stream with count() (or any other operation), but that would be misleading as if I needed some result from Stream termination. What is the correct method to terminate the Stream in such case?

Here is the code for reference:

Stream<Collection<NetworkPart>> graphHolders = cutSegment.stream()
    .map(this::obtainCollectionFor);
for (NetworkPart part : edgesToNetworkParts.get(originalSegment)) {
    part.integrate(cutSegment);
    graphHolders = graphHolders.peek(gh -> gh.add(part));
}
graphHolders.count(); // Just to terminate
like image 966
gvlasov Avatar asked Feb 17 '15 14:02

gvlasov


2 Answers

This is how I've rewritten the code from the question:

Collection<NetworkPart> partsOwningEdge = edgesToNetworkParts.get(originalSegment);
partsOwningEdge.forEach(part -> part.integrate(cutSegment));
cutSegment.stream()
    .map(this::obtainCollectionFor)
    .forEach(gh -> gh.addAll(partsOwningEdge));
like image 103
gvlasov Avatar answered Oct 28 '22 20:10

gvlasov


If it's just the 'misleading' that's irking you, try this:

private static void terminateStream(Stream<?> stream) { 
    stream.forEach(e -> {});
}

I think this would remove any ambiguity: The method has a clear purpose and the call is clear as well. When used as follows,

public static void main(String[] args) {
    Stream<String> stream = Arrays.asList("a", "b", "c").stream();
    stream = stream.peek(str -> System.out.println(str));
    terminateStream(stream);
}

The main method will print

a
b
c

This does require that stream is not closed and has not been operated upon, or it will throw an IllegalStateException.

like image 39
DennisW Avatar answered Oct 28 '22 19:10

DennisW