0% found this document useful (0 votes)
7 views61 pages

Understanding Java Stream API Basics

Uploaded by

adahiya
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views61 pages

Understanding Java Stream API Basics

Uploaded by

adahiya
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

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();

You might also like