Can u help me to understand stream api
Of course Let’s go step by step and keep it simple.
What is Stream API in Java?
● Introduced in Java 8.
● It is used to process collections (List, Set, Map, etc.) in a functional style.
● Instead of writing loops manually, you can filter, transform, and aggregate data in a
clean way.
Think of a stream like a pipeline:
Data goes in → Operations happen step by step → Result comes out.
Why use Stream API?
● Less boilerplate code (no need for too many for-loops).
● Easier to read.
● Supports parallel processing (multi-core performance).
● Functional style programming with lambda expressions.
Important Stream Operations
1. Creating Streams
import [Link].*;
import [Link].*;
public class StreamExample {
public static void main(String[] args) {
List<String> names = [Link]("Aman", "Vinod", "Suresh",
"Ravi");
// Stream creation
Stream<String> j = [Link]();
}
}
2. Intermediate Operations (return Stream again)
These are lazy (executed only when terminal operation is called).
● filter() → keeps elements based on condition
● map() → transforms each element
● sorted() → sorts elements
● distinct() → removes duplicates
● limit(n) / skip(n) → cut the stream
Example:
[Link]()
.filter(n -> [Link]("S")) // keep only names starting
with S
.map(String::toUpperCase) // convert to uppercase
.sorted() // sort alphabetically
.forEach([Link]::println); // print result
Output:
SURESH
3. Terminal Operations (end the stream)
These trigger execution.
● forEach() → loop through
● collect() → convert back to List/Set/Map
● count() → number of elements
● findFirst() / findAny() → get one element
● reduce() → combine into a single result
Example:
List<Integer> numbers = [Link](1, 2, 3, 4, 5);
// Sum using reduce
int sum = [Link]()
.reduce(0, (a, b) -> a + b);
[Link]("Sum = " + sum); // 15
4. Collectors
Used with collect() to gather results.
List<String> result = [Link]()
.filter(n -> [Link]() > 4)
.collect([Link]());
[Link](result); // [Vinod, Suresh]
5. Parallel Streams
For large data, you can process in parallel:
int total = [Link]()
.reduce(0, Integer::sum);
So in short:
● Stream is a pipeline for data processing.
● You chain intermediate operations (filter, map, etc.).
● You finish with a terminal operation (collect, reduce, etc.).
Do you want me to create a visual diagram (like a flowchart) of how Stream pipeline works
(data in → operations → result) so it’s even easier to understand?
Ueah
Hi
Hey! How’s it going?
I didn't understand map and foreach in stream above
No worries let me explain map() and forEach() in Stream API step by step with
examples.
1. map() (Intermediate Operation)
It is used to transform each element of the stream into another form.
● Think of it like: “take each item, apply a function, and return the new value.”
● It doesn’t change the original list — it creates a new stream with transformed data.
Example:
import [Link].*;
class Demo {
public static void main(String[] args) {
List<String> names = [Link]("aman", "vinod", "neha");
// Convert each name to uppercase
List<String> upperNames = [Link]()
.map(name ->
[Link]())
.toList();
[Link](upperNames); // [AMAN, VINOD, NEHA]
}
}
Here:
● map(name -> [Link]()) transforms each element.
● Input: "aman" → Output: "AMAN"
2. forEach() (Terminal Operation)
It is used to consume each element of the stream and perform an action.
● Usually for printing, logging, or calling a method.
● It does not return anything.
Example:
import [Link].*;
class Demo {
public static void main(String[] args) {
List<Integer> numbers = [Link](1, 2, 3, 4, 5);
// Print each number
[Link]()
.forEach(num -> [Link](num));
}
}
Output:
1
2
3
4
5
Here:
● forEach(num -> [Link](num)) goes through each element and
prints it.
● It doesn’t create a new list, just performs an action.
Key Difference
● map() = transforms data → returns a new stream
● forEach() = consumes data → ends the stream (no new data returned)
Do you want me to also show a real-world example where we use both map() and
forEach() together (like processing employee data)?
Yeah
Perfect Let’s take a real-world example with employees.
Suppose you have a list of employees with name + salary and you want to:
1. Increase each salary by 10% (map)
2. Print the updated salary list (forEach)
Example Code
import [Link].*;
class Employee {
String name;
double salary;
Employee(String name, double salary) {
[Link] = name;
[Link] = salary;
}
}
public class Demo {
public static void main(String[] args) {
List<Employee> employees = [Link](
new Employee("Aman", 50000),
new Employee("Vinod", 60000),
new Employee("Neha", 70000)
);
// Step 1: Increase salary by 10% using map
[Link]()
.map(emp -> new Employee([Link], [Link] *
1.10)) // transform salary
// Step 2: Print updated employees using forEach
.forEach(emp -> [Link]([Link] + " -> "
+ [Link]));
}
}
Output:
Aman -> 55000.0
Vinod -> 66000.0
Neha -> 77000.0
What happened here?
● map(emp -> new Employee([Link], [Link] * 1.10)) → created a
new stream of employees with updated salaries.
● forEach(...) → consumed that new stream and printed results.
So, real-world use case = transform (map) data + consume (forEach) data.
Do you also want me to show an example where we collect the updated employees into a new
list (instead of just printing)?
Yeah pps
Great let’s extend the same employee example but this time instead of just printing with
forEach, we’ll use collect() to build a new list of employees with updated salaries.
Example Code with collect
import [Link].*;
import [Link];
class Employee {
String name;
double salary;
Employee(String name, double salary) {
[Link] = name;
[Link] = salary;
}
@Override
public String toString() {
return name + " -> " + salary;
}
}
public class Demo {
public static void main(String[] args) {
List<Employee> employees = [Link](
new Employee("Aman", 50000),
new Employee("Vinod", 60000),
new Employee("Neha", 70000)
);
// Step 1: Increase salary by 10% using map
List<Employee> updatedEmployees = [Link]()
.map(emp -> new Employee([Link], [Link] * 1.10)) //
transform
.collect([Link]()); // collect into new List
// Step 2: Print the new list
[Link]([Link]::println);
}
}
Output
Aman -> 55000.0
Vinod -> 66000.0
Neha -> 77000.0
Key Difference:
● forEach → consumes the stream (used for printing, saving to DB, sending
emails, etc.).
● collect → gathers the results into a new List/Set/Map so you can reuse them
later.
Think of it like this:
● map = changes each item.
● collect = puts results in a new basket.
● forEach = looks at each item one by one and does something (like printing).
Would you like me to also explain the difference between map and flatMap (another
confusing part of streams)?
Can u store this in map like u did in list
Absolutely You can store the stream results in a Map as well using [Link]().
Let’s take the same employee example and instead of storing in a List, we’ll store employees
in a Map<String, Double> where the key = employee name and value = updated salary.
Example Code (collect into Map)
import [Link].*;
import [Link];
class Employee {
String name;
double salary;
Employee(String name, double salary) {
[Link] = name;
[Link] = salary;
}
}
public class Demo {
public static void main(String[] args) {
List<Employee> employees = [Link](
new Employee("Aman", 50000),
new Employee("Vinod", 60000),
new Employee("Neha", 70000)
);
// Collect into Map<name, updatedSalary>
Map<String, Double> salaryMap = [Link]()
.collect([Link](
emp -> [Link], // key
emp -> [Link] * 1.10 // value
));
// Print the Map
[Link]((name, salary) ->
[Link](name + " -> " + salary)
);
}
}
Output
Aman -> 55000.0
Vinod -> 66000.0
Neha -> 77000.0
Notes:
● If two employees have the same name, toMap will throw an error. In that case, you
can use a merge function inside toMap() to handle duplicates.
Example:
[Link](
emp -> [Link],
emp -> [Link],
(salary1, salary2) -> salary1 // keep first if duplicate
);
Do you want me to also show you how to group employees by something (e.g., department)
using [Link]()? That’s the next powerful step after toMap().
Yes please
Perfect let’s level up with [Link]()
This is useful when you want to group objects based on some property (like department,
role, age range, etc.) and then collect them into a Map.
Example: Group employees by department
import [Link].*;
import [Link];
class Employee {
String name;
String department;
double salary;
Employee(String name, String department, double salary) {
[Link] = name;
[Link] = department;
[Link] = salary;
}
}
public class Demo {
public static void main(String[] args) {
List<Employee> employees = [Link](
new Employee("Aman", "IT", 50000),
new Employee("Vinod", "Finance", 60000),
new Employee("Neha", "IT", 70000),
new Employee("Ravi", "HR", 45000),
new Employee("Pooja", "Finance", 55000)
);
// Group employees by department
Map<String, List<Employee>> employeesByDept =
[Link]()
.collect([Link](emp -> [Link]));
// Print the grouped employees
[Link]((dept, emps) -> {
[Link](dept + " -> " +
[Link]().map(e ->
[Link]).collect([Link]())
);
});
}
}
Output
IT -> [Aman, Neha]
Finance -> [Vinod, Pooja]
HR -> [Ravi]
You can go further
Count employees per department
Map<String, Long> empCountByDept = [Link]()
.collect([Link](emp -> [Link],
[Link]()));
Output:
IT -> 2
Finance -> 2
HR -> 1
1.
Average salary per department
Map<String, Double> avgSalaryByDept = [Link]()
.collect([Link](emp -> [Link],
[Link](emp -> [Link])));
Output:
IT -> 60000.0
Finance -> 57500.0
HR -> 45000.0
2.
So basically:
● toMap() → one-to-one mapping (like Name → Salary).
● groupingBy() → one-to-many mapping (like Department → List of
Employees).
Do you want me to also explain nested grouping (e.g., Department → Salary Range →
Employees)? That’s a common interview-level trick.
First tell me what is this 2MAP and distance between 2MAP and grouping by?
Great question Let’s carefully break this down:
What is [Link]() ?
● It is used when you want to collect a Stream into a Map<K, V> directly.
● Each element of the Stream is transformed into a key-value pair.
Example:
Map<String, Double> empSalaryMap = [Link]()
.collect([Link](emp -> [Link], emp -> [Link]));
Output (Name → Salary):
{Aman=50000.0, Vinod=60000.0, Neha=70000.0, Ravi=45000.0,
Pooja=55000.0}
Limitation:
● Keys must be unique.
● If duplicate keys appear → IllegalStateException.
What is [Link]() ?
● It is used when you want to group elements by a classifier (like department, role,
etc.).
● The value is usually a list of elements (or some aggregation, like count, average,
etc.).
Example:
Map<String, List<Employee>> employeesByDept = [Link]()
.collect([Link](emp -> [Link]));
Output (Dept → List of Employees):
IT -> [Aman, Neha]
Finance -> [Vinod, Pooja]
HR -> [Ravi]
Key Difference: toMap() vs groupingBy()
Feature toMap() groupingBy()
Use Case One-to-One mapping (Key → One-to-Many grouping (Key →
Value) List/Count/Aggregation)
Duplicates Not allowed (throws exception Allowed (groups under same key)
unless you handle)
Default Map<K, V> Map<K, List<T>> (can change with
Value Type collectors)
Example Name → Salary Department → List of Employees
Example Together:
// toMap → Name → Salary
Map<String, Double> empSalaryMap = [Link]()
.collect([Link](emp -> [Link], emp -> [Link]));
// groupingBy → Dept → List of Employees
Map<String, List<Employee>> employeesByDept = [Link]()
.collect([Link](emp -> [Link]));
In short:
● Use toMap when you want one unique value per key.
● Use groupingBy when you want to collect multiple values under the same key
(like grouping).
Would you like me to also show you how to handle duplicates in toMap()? That’s a tricky
interview question.
Can you tell me how you calculated the average, like you did something in the grouping by then
you did some calculation of the average that I didn't understand. Can you help me?
Ah, got it You’re asking about the part where I used groupingBy together with an
aggregator like averagingDouble. Let’s break that step by step.
Recap: Normal groupingBy
Map<String, List<Employee>> employeesByDept = [Link]()
.collect([Link](emp -> [Link]));
This groups employees by department into lists.
Example output:
IT -> [Aman, Neha]
Finance -> [Vinod, Pooja]
HR -> [Ravi]
Adding Aggregation (like Average Salary)
Instead of just collecting into a List<Employee>, we can ask Java to do math on the grouped
items.
Example:
Map<String, Double> avgSalaryByDept = [Link]()
.collect([Link](
emp -> [Link], // group by
department
[Link](emp -> [Link]) // calculate
avg salary
));
Output:
IT -> 60000.0
Finance -> 57500.0
HR -> 45000.0
What’s Happening Internally?
1. groupingBy(emp -> [Link], ...)
→ Groups employees into buckets by department.
2. Instead of the default collector (toList()), we pass averagingDouble(emp ->
[Link])
→ For each group, Java sums salaries and divides by number of employees
in that group.
So conceptually:
IT: (50000 + 70000) / 2 = 60000
Finance: (60000 + 55000) / 2 = 57500
HR: (45000) / 1 = 45000
Other Aggregations with groupingBy
You can replace averagingDouble with others:
● [Link]() → count employees per dept
● [Link](emp -> [Link]) → total salary per dept
● [Link](...) / minBy(...) → find highest/lowest salary per
dept
So the "calculation of the average" comes from [Link](...)
inside groupingBy.
Would you like me to also show you how to get multiple aggregations at once (e.g., both
average salary AND employee count in one map)? That’s often asked in interviews.
Yes
Perfect Let’s do multiple aggregations at once using [Link]() with
[Link] or [Link].
This is a common interview-level trick.
Example: Average Salary + Employee Count per Department
import [Link].*;
import [Link];
class Employee {
String name;
String department;
double salary;
Employee(String name, String department, double salary) {
[Link] = name;
[Link] = department;
[Link] = salary;
}
@Override
public String toString() {
return name + " -> " + salary;
}
}
public class Demo {
public static void main(String[] args) {
List<Employee> employees = [Link](
new Employee("Aman", "IT", 50000),
new Employee("Vinod", "Finance", 60000),
new Employee("Neha", "IT", 70000),
new Employee("Ravi", "HR", 45000),
new Employee("Pooja", "Finance", 55000)
);
// Group by department and calculate multiple stats
Map<String, Map<String, Double>> statsByDept =
[Link]()
.collect([Link](
emp -> [Link],
[Link](
[Link](emp -> [Link]),
summary -> {
Map<String, Double> map = new HashMap<>();
[Link]("averageSalary",
[Link]());
[Link]("totalSalary", [Link]());
[Link]("count", (double) [Link]());
return map;
}
)
));
// Print results
[Link]((dept, stats) -> {
[Link](dept + " -> " + stats);
});
}
}
Output
IT -> {averageSalary=60000.0, totalSalary=120000.0, count=2.0}
Finance -> {averageSalary=57500.0, totalSalary=115000.0, count=2.0}
HR -> {averageSalary=45000.0, totalSalary=45000.0, count=1.0}
What’s happening
1. groupingBy(emp -> [Link], ...) → groups employees by
department
2. [Link](emp -> [Link]) → creates a
summary object with:
○ getAverage(), getSum(), getCount(), getMax(), getMin()
3. collectingAndThen(..., summary -> ...) → converts the summary into
a custom map with multiple stats
4. Result = Map<Department, Map<StatName, Value>>
Tip for interviews:
● You can also use [Link]() or [Link]() for
custom calculations.
● Showing knowledge of summarizingDouble + collectingAndThen looks very
strong for a 3-year Spring Boot interview.
If you want, I can also make a visual diagram of stream → grouping →
aggregation → final result, so you can memorize it easily for interviews.
Do you want me to do that?
Ok
No image
Got it! While the image is processing slowly, I can explain the visual flow in text so you can
picture it clearly for interviews:
Stream Pipeline for Grouping & Aggregation (Text Diagram)
[Data Source: List of Employees]
|
v
Stream Creation
|
v
[Intermediate Operations] (Optional: filter, map)
|
v
Terminal Operation:
groupingBy(emp -> [Link])
|
v
Aggregation: summarizingDouble(emp -> [Link])
|
v
Result:
Map<Department, Map<StatName, Value>>
Example:
IT -> {averageSalary=60000, totalSalary=120000, count=2}
Finance -> {averageSalary=57500, totalSalary=115000, count=2}
HR -> {averageSalary=45000, totalSalary=45000, count=1}
Key Notes:
● Intermediate Operations: Transform/filter elements without ending the stream.
● groupingBy: Groups elements under a key (one-to-many).
● summarizingDouble: Calculates multiple stats in one go: avg, sum, count, min, max.
● Result: Nested Map giving per-department stats.
If you want, I can also make a simpler “pocket cheat sheet” for Stream API for all these
operations (map, filter, forEach, collect, groupingBy, summarizingDouble) so you
can revise it quickly before an interview.
Do you want me to do that?
More examples of stream I mean all stream example
Absolutely! Let’s make a complete set of Java Stream API examples covering most common
operations you’ll need for interviews or real projects. I’ll break them into categories with short,
clear examples.
Creating Streams
import [Link].*;
import [Link].*;
List<String> list = [Link]("Aman", "Vinod", "Neha");
// From Collection
Stream<String> stream1 = [Link]();
// From Array
Stream<Integer> stream2 = [Link](new Integer[]{1,2,3,4});
// From [Link]()
Stream<String> stream3 = [Link]("A","B","C");
Intermediate Operations
a) filter() – keeps only elements that match a condition
List<Integer> numbers = [Link](1,2,3,4,5);
List<Integer> even = [Link]()
.filter(n -> n % 2 == 0)
.toList();
[Link](even); // [2, 4]
b) map() – transform elements
List<String> names = [Link]("aman", "vinod");
List<String> upper = [Link]()
.map(String::toUpperCase)
.toList();
[Link](upper); // [AMAN, VINOD]
c) distinct() – remove duplicates
List<Integer> nums = [Link](1,2,2,3,3,3);
List<Integer> unique = [Link]().distinct().toList();
[Link](unique); // [1,2,3]
d) sorted() – sort elements
List<String> names = [Link]("Vinod","Aman","Neha");
List<String> sorted = [Link]().sorted().toList();
[Link](sorted); // [Aman, Neha, Vinod]
e) limit() / skip() – take first N elements or skip N
List<Integer> numbers = [Link](1,2,3,4,5);
List<Integer> first3 = [Link]().limit(3).toList(); // [1,2,3]
List<Integer> skip2 = [Link]().skip(2).toList(); // [3,4,5]
Terminal Operations
a) forEach() – consume elements
List<String> names = [Link]("Aman","Neha");
[Link]().forEach([Link]::println);
b) collect() – gather results
List<String> upperNames = [Link]()
.map(String::toUpperCase)
.collect([Link]());
c) reduce() – combine elements into one
List<Integer> numbers = [Link](1,2,3,4);
int sum = [Link]().reduce(0, Integer::sum);
[Link](sum); // 10
d) count() – count elements
long evenCount = [Link]().filter(n -> n % 2 == 0).count();
[Link](evenCount); // 2
e) findFirst() / findAny() – get one element
Optional<Integer> first = [Link]().filter(n -> n >
2).findFirst();
[Link]([Link]()); // 3
Advanced Operations
a) groupingBy() – group elements
class Employee {
String name; String dept; double salary;
Employee(String n, String d, double s){name=n; dept=d; salary=s;}
}
List<Employee> emp = [Link](
new Employee("Aman","IT",50000),
new Employee("Neha","IT",60000),
new Employee("Vinod","Finance",55000)
);
Map<String, List<Employee>> byDept = [Link]()
.collect([Link](e -> [Link]));
b) averagingDouble() / counting() / summingDouble()
Map<String, Double> avgSalary = [Link]()
.collect([Link](e -> [Link],
[Link](e -> [Link])));
c) flatMap() – flatten nested structures
List<List<String>> listOfLists = [Link](
[Link]("A","B"), [Link]("C","D")
);
List<String> flat = [Link]()
.flatMap(List::stream)
.toList();
[Link](flat); // [A,B,C,D]
d) peek() – debug intermediate operations
[Link]()
.filter(n -> n%2==0)
.peek(n -> [Link]("Even: "+n))
.map(n -> n*2)
.toList();
Parallel Streams
int sumParallel = [Link]().reduce(0, Integer::sum);
Combining Multiple Operations
List<String> result = [Link]()
.filter(e -> [Link] > 50000)
.map(e -> [Link]())
.sorted()
.collect([Link]());
[Link](result); // [NEHA, VINOD]
Summary Cheat Sheet:
Operation Type Examples
Create Stream stream(), [Link](), [Link]()
Intermediate filter, map, distinct, sorted, limit, skip,
peek
Terminal forEach, collect, reduce, count, findFirst
Aggregation groupingBy, averagingDouble, counting,
summingDouble
Flatten flatMap
Parallel parallelStream()
If you want, I can make a single big “ultimate visual cheat sheet” of Stream API with all
operations + examples + arrows so you can memorize it for interviews in 10 mins.
Do you want me to make that?
List out all stream function
Sure! Here’s a comprehensive list of Java Stream API functions broken into categories. I’ll
include almost all commonly used methods that are expected in interviews, along with short
notes.
Stream Creation
● stream() → from Collection
● parallelStream() → from Collection, parallel execution
● [Link](T… values) → from elements
● [Link](array) → from array
● [Link](Supplier<T>) → infinite stream
● [Link](seed, UnaryOperator<T>) → infinite/finite sequence
Intermediate Operations (return Stream, lazy
evaluation)
● filter(Predicate<T> predicate) → keep elements that match condition
● map(Function<T,R> mapper) → transform elements
● mapToInt / mapToLong / mapToDouble → convert to primitive stream
● flatMap(Function<T, Stream<R>> mapper) → flatten nested streams
● distinct() → remove duplicates
● sorted() → natural order
● sorted(Comparator<T>) → custom order
● peek(Consumer<T> action) → debug / side-effects
● limit(long maxSize) → take first N elements
● skip(long n) → skip first N elements
● takeWhile(Predicate<T>) → take until predicate is false (Java 9+)
● dropWhile(Predicate<T>) → drop while predicate is true (Java 9+)
● unordered() → allow unordered execution (parallel optimization)
● onClose(Runnable closeHandler) → close hook
Terminal Operations (consume Stream, triggers
processing)
● forEach(Consumer<T> action) → apply action to each element
● forEachOrdered(Consumer<T>) → ordered version in parallel streams
● toArray() → convert to array
● reduce(BinaryOperator<T> accumulator) → combine elements
● reduce(identity, BinaryOperator<T> accumulator) → combine with
initial value
● collect(Collector<T,A,R> collector) → gather results
● min(Comparator<T>) → minimum element
● max(Comparator<T>) → maximum element
● count() → number of elements
● anyMatch(Predicate<T>) → true if any element matches
● allMatch(Predicate<T>) → true if all elements match
● noneMatch(Predicate<T>) → true if no element matches
● findFirst() → first element (Optional)
● findAny() → any element (Optional)
Specialized Streams (IntStream, LongStream,
DoubleStream)
● range(startInclusive, endExclusive) → generate sequence
● rangeClosed(startInclusive, endInclusive) → generate inclusive
sequence
● sum() → sum of elements
● average() → OptionalDouble
● min() / max() → min/max
● asDoubleStream() / asLongStream() → convert type
● boxed() → convert primitive stream to Stream<T>
Collectors (used with collect())
● [Link]() → collect into List
● [Link]() → collect into Set
● [Link](keyMapper, valueMapper) → collect into Map
● [Link](classifier) → group elements
● [Link](classifier, downstream) → group + aggregate
● [Link](predicate) → partition into true/false
● [Link]() → count elements
● [Link] / averagingDouble / averagingLong →
average
● [Link] / summingDouble / summingLong → sum
● [Link](Comparator) → max element
● [Link](Comparator) → min element
● [Link](delimiter, prefix, suffix) → join strings
● [Link](mapper, downstream) → map + collect
● [Link](collector, finisher) → post-
processing
Optional / Useful Operations
● parallel() → convert stream to parallel
● sequential() → convert stream back to sequential
● isParallel() → check if stream is parallel
● close() → close stream if needed
Tip for interviews:
● Intermediate operations are lazy, i.e., nothing happens until a terminal operation is
called.
● Terminal operations trigger the execution of the whole stream pipeline.
● map() transforms, flatMap() flattens, collect() gathers, groupingBy()
groups.
If you want, I can make a single table of all stream operations with examples — like a cheat
sheet you can memorize for interviews in 10 minutes.
Do you want me to make that cheat sheet?
Ok
Perfect Here’s a complete Stream API cheat sheet — all operations with short examples
— structured for quick memorization for interviews.
Java Stream API Cheat Sheet
Stream Creation
Method Example Notes
stream() [Link]() From Collection
parallelStream [Link]() Parallel execution
()
[Link]() [Link](1,2,3) From elements
[Link]( [Link](arr) From array
)
[Link] [Link](() -> Infinite stream
e() [Link]())
[Link] [Link](0, n -> n+2) Infinite/finite sequence
()
Intermediate Operations (lazy)
Method Example Notes
filter() [Link](n -> n%2==0) Keep elements matching
predicate
map() [Link](String::toUpperCas Transform elements
e)
flatMap() [Link]().flatMap( Flatten nested streams
List::stream)
distinct() [Link]() Remove duplicates
sorted() [Link]() Natural order
sorted(Compa [Link]((a,b)->b-a) Custom order
rator)
peek() [Link]([Link]::print Debug intermediate values
ln)
limit(n) [Link](3) Take first n elements
skip(n) [Link](2) Skip first n elements
takeWhile() [Link](n->n<5) Java 9+, take until predicate
false
dropWhile() [Link](n->n<5) Java 9+, drop while predicate
true
Terminal Operations
Method Example Notes
forEach() [Link]([Link]::pri Consume elements
ntln)
forEachOrdere [Link]().forEachOrder Maintains order in parallel
d() ed(...)
toArray() [Link]() Convert to array
reduce() [Link](0,Integer::sum) Combine elements
collect() [Link]([Link] Gather results
st())
min() / max() [Link](Integer::compare) Min/Max element
count() [Link]() Count elements
anyMatch() [Link](n->n>5) True if any match
allMatch() [Link](n->n>0) True if all match
noneMatch() [Link](n->n<0) True if none match
findFirst() [Link]() Get first element (Optional)
findAny() [Link]() Get any element (Optional)
Specialized Streams
Stream Example Notes
[Link]() [Link](1,5) 1,2,3,4
[Link] [Link](1 1,2,3,4,5
sed() ,5)
sum() [Link](1,2,3).sum Sum of elements
()
average() [Link](1,2,3).ave OptionalDouble
rage()
min() / max() [Link](...).min() Min/Max
boxed() [Link](...).boxed Convert to Stream<Integer>
()
Collectors (with collect())
Collector Example Notes
toList() [Link]([Link]()) List of
elements
toSet() [Link]([Link]()) Set of
elements
toMap() [Link]([Link](e->[Link],e- Map with key-
>[Link])) value
groupingBy() [Link]([Link](e- Group
>[Link])) elements
partitioningB [Link]([Link](n True/False
y() ->n>5)) partition
counting() [Link]([Link]()) Count
elements
averagingInt/ [Link]([Link]( Average
Double/Long e->[Link]))
summingInt/ [Link]([Link](e- Sum
Double/Long >[Link]))
maxBy() / [Link]([Link](Comparator Max/Min
minBy() .comparingInt(e->[Link])))
joining() [Link]([Link](", ")) Join strings
mapping() [Link]([Link](e- Map + collect
>[Link], [Link]()))
collectingAnd [Link]([Link] Post-
Then() n([Link](), List::size)) processing
Other Useful Methods
● parallel() → convert to parallel stream
● sequential() → sequential stream
● isParallel() → check if parallel
● close() → close stream manually
Tips for Interview:
1. Intermediate operations are lazy → don’t execute until terminal operation.
2. map() → transform, flatMap() → flatten, collect() → gather results.
3. groupingBy() + averagingDouble() → average per group.
4. reduce() → combine to single value.
5. peek() → debug inside stream.
If you want, I can also make a super compact “1-page visual stream cheat sheet” with all
operations + arrows + examples for fast memorization before interviews.
Do you want me to make that visual cheat sheet?
I want all of these mentioned examples in detailed explanation
Perfect! Let’s go step by step and go through all the Stream API examples I listed, with
detailed explanations so you can fully understand how each works and why it’s useful. I’ll
break them into sections: Creation, Intermediate, Terminal, Specialized, Collectors, and
Advanced.
Stream Creation
a) stream() – From Collection
List<String> list = [Link]("Aman", "Vinod", "Neha");
Stream<String> stream = [Link]();
Explanation:
● Creates a Stream from a collection (List, Set, etc.).
● Stream represents a pipeline of elements for processing.
b) parallelStream() – Parallel Execution
Stream<String> parallelStream = [Link]();
● Like stream() but can process elements in parallel (multi-threaded).
● Useful for large data sets.
c) [Link]()
Stream<String> s = [Link]("A", "B", "C");
● Creates a stream directly from elements.
d) [Link]()
int[] arr = {1,2,3,4};
IntStream s = [Link](arr);
● Useful for arrays (primitive or object arrays).
e) [Link]() – Infinite Stream
Stream<Double> randomNumbers = [Link](Math::random);
[Link](5).forEach([Link]::println);
● Infinite stream of random numbers.
● Must use limit() to prevent infinite loop.
f) [Link]() – Infinite/Sequence
Stream<Integer> seq = [Link](0, n -> n + 2);
[Link](5).forEach([Link]::println); // 0,2,4,6,8
● Generates a sequence based on a function applied repeatedly.
Intermediate Operations (Lazy)
a) filter() – Keep elements matching condition
List<Integer> numbers = [Link](1,2,3,4,5);
List<Integer> even = [Link]()
.filter(n -> n % 2 == 0)
.toList();
● Only elements where n % 2 == 0 are kept.
● Lazy: nothing happens until a terminal operation (toList) is called.
b) map() – Transform elements
List<String> names = [Link]("aman", "vinod");
List<String> upper = [Link]()
.map(String::toUpperCase)
.toList();
● Transforms each element (map) to another form (toUpperCase).
c) flatMap() – Flatten nested structures
List<List<String>> listOfLists = [Link](
[Link]("A","B"), [Link]("C","D")
);
List<String> flat = [Link]()
.flatMap(List::stream)
.toList();
● Flattens List<List<T>> into List<T>.
d) distinct() – Remove duplicates
List<Integer> nums = [Link](1,2,2,3,3,3);
List<Integer> unique = [Link]().distinct().toList();
● Removes duplicate elements in the stream.
e) sorted() / sorted(Comparator)
List<String> names = [Link]("Vinod","Aman","Neha");
List<String> sorted = [Link]().sorted().toList(); // Natural
List<String> reverse =
[Link]().sorted([Link]()).toList(); // Custom
● Natural order or custom comparator.
f) limit(n) / skip(n)
List<Integer> numbers = [Link](1,2,3,4,5);
[Link]().limit(3).toList(); // [1,2,3]
[Link]().skip(2).toList(); // [3,4,5]
● Limit: first N elements.
● Skip: ignore first N elements.
g) peek() – Debug elements
[Link]()
.filter(n -> n % 2 == 0)
.peek(n -> [Link]("Even: "+n))
.map(n -> n*2)
.toList();
● Inspect elements in the middle of a stream pipeline without consuming them.
Terminal Operations
a) forEach()
[Link]().forEach([Link]::println);
● Consumes each element.
● Terminal operation; triggers pipeline execution.
b) collect() → Gather results
List<String> upperNames = [Link]()
.map(String::toUpperCase)
.collect([Link]());
● Collects results into a collection (List, Set, Map).
c) reduce() – Combine elements
List<Integer> numbers = [Link](1,2,3,4);
int sum = [Link]().reduce(0, Integer::sum);
● Combines elements using a binary operation (+).
● 0 is identity (initial value).
d) count()
long evenCount = [Link]().filter(n -> n % 2 == 0).count();
● Counts elements in the stream (after intermediate operations).
e) anyMatch(), allMatch(), noneMatch()
boolean any = [Link]().anyMatch(n->n>4); // true
boolean all = [Link]().allMatch(n->n>0); // true
boolean none = [Link]().noneMatch(n->n<0); // true
● Boolean checks across elements.
f) findFirst() / findAny()
Optional<Integer> first = [Link]().filter(n ->
n>2).findFirst();
[Link]([Link]()); // 3
● Returns Optional of element.
● findAny() may return any element in parallel streams.
Specialized Streams
a) [Link]()
[Link](1,5).forEach([Link]::println); // 1,2,3,4
● Excludes end value.
b) [Link]()
[Link](1,5).forEach([Link]::println); // 1,2,3,4,5
c) sum(), average(), min(), max()
int sum = [Link](1,2,3).sum(); // 6
OptionalDouble avg = [Link](1,2,3).average(); // 2.0
d) boxed() – Convert to object stream
List<Integer> list = [Link](1,2,3).boxed().toList();
Collectors (collect)
a) toList(), toSet(), toMap()
List<String> list = [Link]().collect([Link]());
Set<String> set = [Link]().collect([Link]());
Map<String,Integer> map = [Link]().collect([Link](n-
>n,n->[Link]()));
b) groupingBy() – Group elements
Map<String, List<Employee>> byDept = [Link]()
.collect([Link](e -> [Link]));
c) Aggregations
Map<String, Double> avgSalary = [Link]()
.collect([Link](
e -> [Link],
[Link](e -> [Link])
));
d) Multiple Aggregations
Map<String, Map<String, Double>> statsByDept = [Link]()
.collect([Link](
e -> [Link],
[Link](
[Link](e -> [Link]),
s -> {
Map<String, Double> map = new HashMap<>();
[Link]("avg", [Link]());
[Link]("sum", [Link]());
[Link]("count", (double)[Link]());
return map;
}
)
));
Parallel Streams
int sumParallel = [Link]().reduce(0, Integer::sum);
● Stream executes operations in parallel threads.
Combining Operations
List<String> result = [Link]()
.filter(e -> [Link] > 50000)
.map(e -> [Link]())
.sorted()
.collect([Link]());
● Shows multiple intermediate operations combined, terminated with collect().
Key Notes
1. Intermediate operations: lazy → filter, map, distinct, sorted.
2. Terminal operations: trigger execution → forEach, collect, reduce, count.
3. Specialized streams: IntStream, DoubleStream, LongStream.
4. Collectors: powerful for grouping, aggregating, mapping, joining.
5. Parallel streams: useful for large data sets.
I can also make a visual “all-in-one Stream API diagram” showing flow from creation →
intermediate → terminal → collect → aggregation with arrows and examples — like
a single-page cheat sheet for interviews.
Do you want me to make that visual cheat sheet?
Mapping example nhi h
Ah yes! Let me give you a clear, detailed explanation of mapping() in streams with
examples.
[Link]()
● mapping() is a downstream collector used with collect(), usually in
combination with groupingBy() or other collectors.
● It applies a function to each element before passing it to another collector.
Example 1: Simple Mapping
List<String> names = [Link]("Aman", "Vinod", "Neha");
List<String> upperNames = [Link]()
.collect([Link](
String::toUpperCase,
[Link]()
));
[Link](upperNames); // [AMAN, VINOD, NEHA]
Explanation:
1. String::toUpperCase → transforms each element.
2. [Link]() → collects the transformed elements into a list.
Example 2: Grouping + Mapping
class Employee {
String name;
String dept;
Employee(String n, String d){ name=n; dept=d; }
}
List<Employee> emp = [Link](
new Employee("Aman","IT"),
new Employee("Neha","IT"),
new Employee("Vinod","Finance")
);
Map<String, List<String>> namesByDept = [Link]()
.collect([Link](
e -> [Link], // Group by department
[Link](
e -> [Link], // Map employee to name
[Link]() // Collect names into list
)
));
[Link](namesByDept);
// Output: {IT=[Aman, Neha], Finance=[Vinod]}
Explanation:
1. groupingBy(e -> [Link]) → groups employees by department.
2. mapping(e -> [Link], toList()) → transforms employees into names,
collects as a list per group.
Example 3: Mapping + Joining
String namesStr = [Link]()
.collect([Link](
e -> [Link],
[Link](", ")
));
[Link](namesStr); // "Aman, Neha, Vinod"
Explanation:
● Maps each employee to their name.
● Joins all names into a single string separated by commas.
Key Points
● mapping() is used to transform elements before the final collector.
● Often used with groupingBy or partitioningBy.
● Can combine with toList(), joining(), counting(), etc.
If you want, I can make a visual diagram showing groupingBy + mapping + collect
pipeline like we did for groupingBy + averaging — this makes it super easy to remember for
interviews.
Do you want me to make that visual diagram?
Can u give me some questions on stream api to test my knowledge
Absolutely! Here’s a set of progressive Stream API questions to test your knowledge. I’ve
categorized them from basic → intermediate → advanced.
Basics
1. How do you create a Stream from:
○ A List
○ An array
○ Direct elements ([Link])
2. Given a list of integers [1,2,3,4,5], write a stream to:
○ Print all elements
○ Print only even numbers
3. Convert a list of lowercase strings ["a", "b", "c"] to uppercase using streams.
4. How do you remove duplicates from a list using streams?
Intermediate
5. Given a list of integers [1,2,3,4,5,6], write a stream to:
○ Multiply each number by 2
○ Collect results into a List
6. What is the difference between map() and flatMap()? Give an example.
7. Use peek() to debug elements of a stream that are greater than 3.
8. Write a stream pipeline to:
○ Skip the first 2 elements
○ Take the next 3 elements
○ Sort them in descending order
9. What is the difference between forEach() and forEachOrdered()?
Advanced
10. Given a list of employees with fields name, dept, salary, write a stream to:
○ Group employees by department
○ Collect only their names in a list per department
11. How do you calculate average salary per department using streams?
12. Using streams, how can you:
○ Partition employees into two groups: salary > 50000 and <= 50000?
13. Explain how reduce() works. Give an example to compute:
○ Sum of integers
○ Product of integers
14. Given a list of words, how can you count the frequency of each word using streams?
15. Using a list of integers, find the first even number greater than 10 using streams.
Expert / Real-world
16. Explain the difference between parallelStream() and stream(). When would
you use parallel streams?
17. Given a list of sentences, how can you get a list of all unique words?
18. Combine filter + map + collect to convert a list of names to uppercase, remove
duplicates, and sort them.
19. Explain the difference between groupingBy() and partitioningBy(). Give an
example for each.
20. Given a map of dept → List<Employee>, write a stream to get department names
where average salary > 50000.
If you want, I can also create answers and example code for all these 20 questions with
detailed explanations, so you can practice and memorize for interviews.
Do you want me to do that?
Please provide me the answer of these questions, 20 questions.
Perfect! Let’s go question by question and provide answers with examples for all 20 Stream
API questions. I’ll make it detailed and beginner-friendly.
Basics
1. Create Streams
// From List
List<Integer> list = [Link](1,2,3);
Stream<Integer> stream1 = [Link]();
// From array
int[] arr = {1,2,3};
IntStream stream2 = [Link](arr);
// From elements
Stream<String> stream3 = [Link]("A","B","C");
2. Print all elements / only even numbers
List<Integer> numbers = [Link](1,2,3,4,5);
// Print all
[Link]().forEach([Link]::println);
// Print even
[Link]().filter(n -> n % 2 == 0).forEach([Link]::println);
3. Convert lowercase strings to uppercase
List<String> names = [Link]("a","b","c");
List<String> upper = [Link]()
.map(String::toUpperCase)
.collect([Link]());
4. Remove duplicates
List<Integer> nums = [Link](1,2,2,3,3,3);
List<Integer> unique =
[Link]().distinct().collect([Link]());
Intermediate
5. Multiply each number by 2 and collect
List<Integer> numbers = [Link](1,2,3,4,5,6);
List<Integer> doubled = [Link]()
.map(n -> n*2)
.collect([Link]());
6. Difference between map() and flatMap()
// map() - transforms each element
List<String> words = [Link]("Hi", "Bye");
List<Integer> lengths = [Link]()
.map(String::length)
.collect([Link]()); // [2,3]
// flatMap() - flattens nested streams
List<List<String>> listOfLists = [Link](
[Link]("A","B"),
[Link]("C","D")
);
List<String> flat = [Link]()
.flatMap(List::stream)
.collect([Link]()); //
[A,B,C,D]
7. Using peek() to debug
[Link]()
.filter(n -> n > 3)
.peek(n -> [Link]("Filtered: "+n))
.map(n -> n*2)
.collect([Link]());
8. Skip 2, take 3, sort descending
[Link]()
.skip(2)
.limit(3)
.sorted([Link]())
.collect([Link]());
9. Difference forEach() vs forEachOrdered()
● forEach() → no guarantee of order in parallel streams
● forEachOrdered() → maintains encounter order, even in parallel
Advanced
10. Group employees by dept, collect names
Map<String, List<String>> namesByDept = [Link]()
.collect([Link](
e -> [Link],
[Link](e -> [Link], [Link]())
));
11. Average salary per department
Map<String, Double> avgSalary = [Link]()
.collect([Link](
e -> [Link],
[Link](e -> [Link])
));
12. Partition employees by salary
Map<Boolean, List<Employee>> partitioned = [Link]()
.collect([Link](e -> [Link] > 50000));
13. reduce() – sum / product
List<Integer> nums = [Link](1,2,3,4);
// Sum
int sum = [Link]().reduce(0, Integer::sum);
// Product
int product = [Link]().reduce(1, (a,b) -> a*b);
14. Count word frequency
List<String> words = [Link]("hi","hello","hi");
Map<String, Long> freq = [Link]()
.collect([Link](w -> w, [Link]()));
15. First even number > 10
Optional<Integer> first = [Link]()
.filter(n -> n > 10 && n % 2 == 0)
.findFirst();
Expert / Real-world
16. stream() vs parallelStream()
● stream() → sequential processing
● parallelStream() → processes elements in multiple threads, faster for large
datasets
● Use parallel when computation is heavy and data is large, order doesn’t matter
17. List of unique words from sentences
List<String> sentences = [Link]("Hi Aman", "Hi Vinod");
List<String> uniqueWords = [Link]()
.flatMap(s -> [Link]([Link](" ")))
.distinct()
.collect([Link]());
18. Filter + map + collect
List<String> result = [Link]()
.map(String::toUpperCase)
.distinct()
.sorted()
.collect([Link]());
19. groupingBy() vs partitioningBy()
// Grouping
Map<String, List<Employee>> byDept = [Link]()
.collect([Link](e -> [Link]));
// Partitioning
Map<Boolean, List<Employee>> highSalary = [Link]()
.collect([Link](e -> [Link] > 50000));
● groupingBy → many groups (key = any value)
● partitioningBy → only 2 groups (true/false)
20. Departments with avg salary > 50k
Map<String, Double> avgSalary = [Link]()
.collect([Link](
e -> [Link],
[Link](e -> [Link])
));
List<String> depts = [Link]().stream()
.filter(e -> [Link]() > 50000)
.map([Link]::getKey)
.collect([Link]());
Tips for Interviews
● Practice groupingBy + mapping + averaging patterns.
● Understand map vs flatMap clearly.
● Always remember intermediate vs terminal operations.
● Know parallelStream pros and cons.
● Optional + filter + findFirst/findAny is common in real scenarios.
If you want, I can now make a single-page “all-in-one Stream API examples with answers”
PDF-style cheat sheet for you, where all 20 questions + code + explanation are on one
page, perfect for last-minute interview prep.
JAVA STREAM API – COMPLETE CHEAT
SHEET (3+ YOE)
1. Stream Creation
[Link]();
[Link]();
[Link]("A","B","C");
[Link](arr);
[Link](1,5);
2. Print Elements / Filter
[Link]().forEach([Link]::println);
[Link]()
.filter(n -> n % 2 == 0)
.forEach([Link]::println);
3. map() – Transform Data
[Link]()
.map(String::toUpperCase)
.collect([Link]());
➡ Converts each element
4. distinct() – Remove Duplicates
[Link]().distinct().collect([Link]());
5. Multiply & Collect
[Link]()
.map(n -> n * 2)
.collect([Link]());
6. map() vs flatMap()
// map
[Link]().map(String::length);
// flatMap
[Link]().flatMap(List::stream);
➡ map = one-to-one
➡ flatMap = one-to-many (flattens)
7. peek() – Debug
[Link]()
.filter(n -> n > 3)
.peek([Link]::println)
.map(n -> n * 2)
.toList();
8. skip + limit + sort
[Link]()
.skip(2)
.limit(3)
.sorted([Link]())
.toList();
9. forEach vs forEachOrdered
● forEach() → order not guaranteed (parallel)
● forEachOrdered() → maintains order
10. groupingBy + mapping
[Link]()
.collect([Link](
e -> [Link],
[Link](e -> [Link], [Link]())
));
11. Average Salary per Dept
[Link]()
.collect([Link](
e -> [Link],
[Link](e -> [Link])
));
12. partitioningBy
[Link]()
.collect([Link](e -> [Link] > 50000));
➡ Always returns Map<Boolean, List<T>>
13. reduce() – Sum / Product
[Link]().reduce(0, Integer::sum);
[Link]().reduce(1, (a,b) -> a*b);
14. Word Frequency
[Link]()
.collect([Link](w -> w, [Link]()));
15. First Even > 10
[Link]()
.filter(n -> n > 10 && n % 2 == 0)
.findFirst();
16. stream() vs parallelStream()
stream parallelStream
Single thread Multi-thread
Ordered Unordered
Small data Large data
17. Unique Words from Sentences
[Link]()
.flatMap(s -> [Link]([Link](" ")))
.distinct()
.toList();
18. Filter + Map + Sort
[Link]()
.filter(n -> [Link]() > 3)
.map(String::toUpperCase)
.sorted()
.toList();
19. groupingBy vs partitioningBy
groupingBy → multiple keys
partitioningBy → only true / false
20. Dept with Avg Salary > 50k
[Link]()
.collect([Link](
e -> [Link],
[Link](e -> [Link])
))
.entrySet().stream()
.filter(e -> [Link]() > 50000)
.map([Link]::getKey)
.toList();