What is the Stream API in Java, and what problem does it solve?
The Stream API gives Java a way to express data transformations — filtering, mapping, aggregating — as a pipeline of operations rather than as a sequence of loops and temporary collections. It arrived alongside lambdas and the functional interfaces, and it is the biggest single change to how everyday Java code is written.
The problem it solves is not performance. It is that the imperative style scatters the intent of a computation across several statements and an ever-growing set of mutable variables. A stream version states what you want: take these elements, keep the ones that match, transform them, collect the result. The intermediate steps are named, so a reader can follow the shape of the computation without tracing variable mutations.
Three properties define a stream. It is not a data structure — it does not hold the elements, it computes them. It is lazy — the work happens only when a terminal operation is called, and elements are pulled through the pipeline one at a time. And it is single-use — once it has been consumed, the pipeline is spent.
The API has three families of methods. Intermediate operations such as filter, map, sorted and distinct return a new stream and do no work themselves. Terminal operations such as forEach, count, collect and anyMatch trigger the pipeline and produce a result or a side effect. And short-circuiting operations such as findFirst and limit stop the pipeline early once the answer is known, which is what makes streams efficient for large or infinite sources.