问题描述:

Each method in Stream and BaseStream neatly specifies if the operation is intermediate or (short-circuiting) terminal.

The exception is the close() method which only states that close handlers be called.

I'm assuming that close() is a terminal operation and that invoking other methods will result in an IllegalStateException. However, as it stands it seems to be up to the implementation to decide this.

Is this omission in the Javadoc an oversight or is this deliberate and am I missing something?

网友答案:

I would argue that Stream.close() can be considered as a terminal operation. An operation in a stream pipeline that takes a stream as input and produces a result or side-effect. After the terminal operation is performed, the stream pipeline is considered consumed, and can no longer be used.

Now if you check the implementation of the close() operation, it is as follows:

public void close() {
    linkedOrConsumed = true; // it sets the flag consumed as true

And now if you try to access the stream say using a map operation, you are going to get an IllegalStateException as there are checks during the construction process of ReferencePipelines.

    if (previousStage.linkedOrConsumed)
        throw new IllegalStateException(MSG_STREAM_LINKED);

Try with the following code:

    Stream<String> stream = Arrays.stream(myStringNumbers); 
    stream.close();
    List<Integer> list1 = stream.map(Integer::parseInt).collect(toList());

The above code will throw IllegalStateException.

网友答案:

Stream.close() is neither, an intermediate operation nor a terminal operation. It isn’t actually an operation (in the sense of the Stream API) at all. Recall that after invoking a terminal operation, you are not allowed to invoke another operation on the same stream.

However, it is not only allowed but the intended use of close() to be invoked on a Stream after the terminal operation, so it isn’t a stream operation of that kind. The action of closing the stream has the same property as terminal operations of forbidding follow-up operations on the Stream (in case they weren’t already forbidden due to a commenced terminal operation) and that’s admittedly a bit underspecified.

But on the other hand, it’s the normal behavior of a close operation of making a resource or object unusable for follow-up operations, so it shouldn’t come at a surprise that this also holds for Streams.

In practice, the well-known error message speaks for itself as it names “has been operated upon” or “closed” as two equal reasons for rejecting follow-up operations.

相关阅读:
Top