-1

Let's imagine the following code:

Stream<Integer> numberStream = ...;

Predicate<Integer> isEven = ...;
Predicate<Integer> isOdd = ...;

List<Integer> evenNumbers = numberStream
    .filter(isEven)
    .collect(Collectors.toList());

List<Integer> oddNumbers = numberStream 
    .filter(isOdd)
    .collect(Collectors.toList()); // this line will throw IllegalStateException

The above code compiles without any warnings. However, trying to run it will always result in an IllegalStateException.

After looking into it, I found out that one Stream can only have one terminal operation, so basically there is no point in storing it inside a variable.

It seems to me that this would be a very easy error to spot by the compiler. Why does it compile without errors? Is there some use case where code like that would be useful?

Stefan Zobel
  • 3,182
  • 7
  • 28
  • 38
KrohnicDev
  • 355
  • 2
  • 12
  • 3
    Short answer: the fact that a stream can't be reused isn't (and can't) be encoded in the Java type system. The compiler doesn't **know** anything about streams (other than the classes used). – Joachim Sauer Apr 21 '20 at 09:31
  • 2
    The compiler checks that the code you've written conforms to the specs defined by the Java Language. But it does **not** check that the code is **correct** in the applied sense. I think you're looking for a java linter plugin for your IDE or maven / gradle build. Sonar may also be an option too – Lino Apr 21 '20 at 09:32

1 Answers1

2

The compiler is simple, in a sense.

It verifies that your code is legal according to the rules of the Java language and that all your calls match what the Java language rules and type system requires.

Neither the language rule nor the type system somehow "encodes" that a Stream can not be reused. It's simply a fact that the compiler doesn't know about.

Think of streams as a domain-specific language built on top of Java. The compiler only knows the lower "Java" layer of that concept, but doesn't understand the rules of the higher-level Streams "language".

So while the compiler could conceivably be told about the rules of that specific language, this is a dangerous road to go, because there are many, many domain specific languages like that which one could conceivably want to verify and doing them all right is ... unlikely.

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614