ProgrammingJava Developer

Explain what Java Stream API is, how to properly use it for collection processing operations, and what nuances to consider when working with data streams?

Pass interviews with Hintsage AI assistant

Answer.

History of the Question:

Stream API was added in Java 8 to facilitate functional programming and parallel processing of collections. It provides a convenient way to describe chains of operations on data using lambda expressions.

The Problem:

Without Stream API, one had to write cumbersome imperative code for filtering, sorting, and aggregating collections. There was a potential for errors, maintenance complexity, and inefficiency when trying to add parallelism manually.

The Solution:

Stream API allows constructing a pipeline of intermediate and terminal operations. Streams are lazy, process data sequentially or in parallel, and make the code more compact and expressive.

Example of collection processing:

List<String> names = Arrays.asList("Anna", "Ivan", "Petr", "Eva"); names.stream() .filter(s -> s.length() > 3) .map(String::toUpperCase) .sorted() .forEach(System.out::println);

Key features:

  • Streams are lazy: calculations occur only during a terminal operation
  • After a terminal operation, the stream is considered closed
  • It is possible to switch to parallel processing (parallelStream()), but thread-safety of collections and functions should be considered

Tricky Questions.

Can you reuse the same Stream after it is closed?

No, attempting to reuse a closed Stream throws an IllegalStateException. A stream is one-time use.

Does changing the original collection after creating a Stream affect it?

Yes, if the collection is modified after the Stream is created but before the terminal operation, ConcurrentModificationException may occur.

Can external mutable variables be used within Stream operations?

It is not recommended, as it can lead to unexpected errors in a parallel stream. It is better to avoid mutable side-effects in the Stream pipeline.

Common Mistakes and Anti-patterns

  • Using mutable external variables inside lambda/stream
  • Expecting immediate effects from intermediate operations (nothing happens without a terminal operation)
  • Applying .parallelStream() to non-thread-safe collections

Real-life Example

Negative Case

A programmer invokes a method through Stream that modifies an external list — this works in sequential execution, but in parallel it causes disruption of the data structure.

Pros:

  • Code is compact

Cons:

  • Possible race conditions, exceptions
  • Breach of thread-safety

Positive Case

The entire pipeline is built cleanly: operations have no side effects, only immutable collections are used, and the final result is collected through a collector.

Pros:

  • Safe, readable, efficient code
  • Easy transition to parallel streams

Cons:

  • Requires adaptation to functional style