Lambdas & Streams
Lambdas β Functions as Values
Before Java 8, if you wanted to pass a piece of behavior to a method, you had to create a whole class. It was like writing a full letter when all you needed was a sticky note. Lambdas are those sticky notes β tiny, anonymous functions you can pass around.
The syntax is simple: (parameters) -> expression
Some examples:
(a, b) -> a + bβ takes two values, returns their sum(s) -> s.length()β takes a string, returns its length() -> System.out.println("Hello!")β takes nothing, prints hello
Lambdas work with functional interfaces β interfaces with exactly one abstract method. You can use them with collections like Maps and Sets to write concise data-processing code. Java provides many built-in ones like Predicate (test), Function (transform), Consumer (act on), and Comparator (compare).
Lambda Basics & Functional Interfaces
Streams β Processing Data Like a Pipeline
Think of a stream as a conveyor belt in a factory. Data items go in one end, pass through various stations (filter, transform, sort), and come out the other end as a finished product.
Streams don't change the original data β they create a new result. Understanding how chained operations affect time complexity helps you write efficient pipelines. They're also lazy: nothing actually happens until you call a terminal operation (like collect(), forEach(), or count()).
Common stream operations:
filter()β keep only items that match a conditionmap()β transform each item into something elsesorted()β put items in orderreduce()β combine all items into one resultcollect()β gather results into a list, set, or other collection
Streams in Action
Streams with Strings & Method References
::) are just shorthand for simple lambdas. String::toUpperCase is the same as s -> s.toUpperCase(). Use them when the lambda just calls a single method β it makes your code read like English. System.out::println, Integer::parseInt, Math::max β clean and clear.