cold water

I just had a stream of objects I wanted to sort and convert to a list. Optionally it should also be limited to a maximum number of entries. Piece of cake with Java 8:

Stream<T> stream = collection.stream().sorted(comparator);
if (max >= 0) {
  stream.limit(max);
}
List<T> result = stream.collect(Collectors.toList());

Or so I thought... The code above throws an IllegalStateException at runtime, stating that the "stream has already been operated upon or closed".

The cause should be obvious. However it took me a while to find it, so I am posting it in case other people (possibly you when you came here via search engine) get stuck at the same place. Stream operations are very likely to return a different Stream object. The limit() method is such an example. In my code above, limit() operates on the stream and returns a limited stream. However I just throw away the returned stream and invoke collect() on the original stream, which was now already operated upon.

The solution is simple:

if (max >= 0) {
  stream = stream.limit(max);
}