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

Java 8 Functional Streams

The document provides an overview of Java 8's Functional Streams API, showcasing various operations such as filtering, mapping, and reducing on a set of categories and products in an e-commerce application. It includes code examples demonstrating how to manipulate and analyze product data using streams, including grouping, partitioning, and calculating statistics. The document serves as a practical guide for utilizing the Streams API to perform complex data operations efficiently.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views14 pages

Java 8 Functional Streams

The document provides an overview of Java 8's Functional Streams API, showcasing various operations such as filtering, mapping, and reducing on a set of categories and products in an e-commerce application. It includes code examples demonstrating how to manipulate and analyze product data using streams, including grouping, partitioning, and calculating statistics. The document serves as a practical guide for utilizing the Streams API to perform complex data operations efficiently.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Java 8 (Modern Java) Functional Streams API & examples

Consider following core classes (POJOs – Plain Old Java Object | Model | Entity) , from typical
Ecommerce application.

public class Category {

private int categoryId

private String name; //unique

private String description;

private List<Product> products=new ArrayList<>();

//constructor , getters setters

public class Product {

private int productId;

private String name;//unique

private double price;

private int quantity;

private LocalDate manufactureDate;

private Category category;

//constructor , getters setters

// Sample Data

Category electronics = new Category(1, "Electronics", "Electronic devices", new ArrayList<>());


Category groceries = new Category(2, "Groceries", "Daily essentials", new ArrayList<>());

Product p1 = new Product(101, "Laptop", 90000, 5, [Link](2024, 1, 10), electronics);

Product p2 = new Product(102, "Mobile", 50000, 10, [Link](2023, 11, 20), electronics);

Product p3 = new Product(103, "TV", 30000, 3, [Link](2024, 5, 15), electronics);

Product p4 = new Product(201, "Rice", 50, 100, [Link](2025, 1, 1), groceries);

Product p5 = new Product(202, "Milk", 30, 50, [Link](2025, 2, 1), groceries);

[Link]().addAll([Link](p1, p2, p3));

[Link]().addAll([Link](p4, p5));

List<Category> categories = [Link](electronics, groceries);


// STREAM EXAMPLES

1. filter → Get all products above 40,000

List<Product> expensive = [Link]() //Stream<Category>

.flatMap(c -> [Link]().stream()) //Stream<Product>

.filter(p -> [Link]() > 40000) //filtered Stream<Product>

.collect([Link]()); //List<Product>

[Link]("Expensive products (>40k): " + expensive);

2. map → Extract product names

List<String> names = [Link]()

.flatMap(c -> [Link]().stream())

.map(Product::getName)//Using Method reference, lambda – p-> [Link]() ,


Stream<String>

.collect([Link]());

[Link]("Product names: " + names);

3. flatMap → Get all products in one list

List<Product> allProducts = [Link]()

.flatMap(c -> [Link]().stream())

.collect([Link]());

[Link]("All products: " + allProducts);

4. reduce → Total value of all products (price * quantity)

double totalValue = [Link]()

.flatMap(c -> [Link]().stream())

.mapToDouble(p -> [Link]() * [Link]()) //DoubleStream containing total product


price

.reduce(0.0, Double::sum); //OR simply .sum()

[Link]("Total stock value = " + totalValue);

5. collect → Group by category name


Map<String, List<Product>> productsByCategory = [Link]()

.collect([Link](

Category::getName,//key mapper function

Category::getProducts//value mapper function

));

[Link]("Products by category: ");

[Link]((k,v) -> [Link](k+” “+v));

6. findAny → Get any product cheaper than 100

Product cheap = [Link]()

.flatMap(c -> [Link]().stream())

.filter(p -> [Link]() < 100)

.findAny()

.orElseThrow(() -> new ProductHandlingException(“Cheap product not found !!!!”));

[Link]("Any cheap product: " + cheap);

7. min & max

Product cheapest = [Link]()

.flatMap(c -> [Link]().stream())

.min([Link](Product::getPrice))//or use usual lambda here – based


on price

.orElse(null);

[Link]("Cheapest product = " + cheapest);

Product costliest = [Link]()

.flatMap(c -> [Link]().stream())

.max([Link](Product::getPrice))

.orElse(null);

[Link]("Costliest product = " + costliest);

8. Display products sorted (by price)


[Link]()

.flatMap(c -> [Link]().stream())

.sorted([Link](Product::getPrice))

.forEach([Link]::println);

9. distinct

List<String> distinctCategoryNames = [Link]()

.map(Category::getName)

.distinct()

.collect([Link]());

[Link]("Distinct category names: " + distinctCategoryNames);

10. anyMatch, allMatch, noneMatch

boolean hasExpensive = [Link]()

.flatMap(c -> [Link]().stream())

.anyMatch(p -> [Link]() > 80000);

[Link]("Any product >80k? " + hasExpensive);

boolean allAffordable = [Link]()

.flatMap(c -> [Link]().stream())

.allMatch(p -> [Link]() < 10000);

[Link]("All affordable (<10K)? " + allAffordable);

boolean noneFree = [Link]()

.flatMap(c -> [Link]().stream())

.noneMatch(p -> [Link]() == 0);

[Link]("No free products? " + noneFree);

11. forEach

[Link]("Print all products:");


[Link]()

.flatMap(c -> [Link]().stream())

.forEach([Link]::println);

12. Group products by category name

List<Product> allProducts = [Link]()

.flatMap(c -> [Link]().stream())

.collect([Link]());

[Link]("All products: " + allProducts);

Map<String, List<Product>> productsByCategory = [Link]()

.collect([Link](p -> [Link]().getName()));

[Link]((k,v) -> [Link](k+” “+v));

13. Count products per category

Map<String, Long> countByCategory = [Link]()

.collect([Link](p -> [Link]().getName(), [Link]()));

[Link]((k,v) -> [Link](k+” “+v));

14. Average price per category

Map<String, Double> avgPriceByCategory = [Link]()

.collect([Link](p -> [Link]().getName(),

[Link](Product::getPrice)));

[Link]((k,v) -> [Link](k+” “+v));

15. Total stock value per category (sum of price*qty)

Map<String, Double> totalStockValue = [Link]()

.collect([Link](p -> [Link]().getName(),

[Link](p -> [Link]() * [Link]())));

[Link]("Total stock value per category: " );

[Link]((k,v) -> [Link](k+” “+v));


16. Partition products into expensive vs cheap (threshold = 5000)

Map<Boolean, List<Product>> partitioned = [Link]()

.collect([Link](p -> [Link]() > 5000));

[Link]("Partitioned products (expensive vs cheap): ");

[Link]((k,v) -> [Link](k+” “+v));

17. Join product names into string

String productNames = [Link]()

.map(Product::getName)

.collect([Link](", ", "[", "]"));//delimiter , prefix,suffix

[Link]("All product names: "+productNames);

18. Max price per category

Map<String, Optional<Product>> maxPriceByCategory = [Link]()

.collect([Link](p -> [Link]().getName(),

[Link]([Link](Product::getPrice))));

[Link]("Max priced product per category: ");

[Link]((k,v)-> [Link](k+” “+v));

19. Mapping products to just names per category

Map<String, List<String>> productNamesByCategory = [Link]()

.collect([Link](p -> [Link]().getName(),

[Link](Product::getName, [Link]())));

[Link]("Product names per category: " );

[Link]((k,v)-> [Link](k+” “+v));

// Sample Data
Category electronics = new Category(1, "Electronics", "Electronic devices", new ArrayList<>());

Category groceries = new Category(2, "Groceries", "Daily essentials", new ArrayList<>());

Category clothing = new Category(3, "Clothing", "Fashion wear", new ArrayList<>());

Product p1 = new Product(101, "Laptop", 90000, 5, [Link](2024, 1, 10), electronics);

Product p2 = new Product(102, "Mobile", 50000, 10, [Link](2023, 11, 20), electronics);

Product p3 = new Product(103, "TV", 30000, 3, [Link](2024, 5, 15), electronics);

Product p4 = new Product(201, "Rice", 50, 100, [Link](2025, 1, 1), groceries);

Product p5 = new Product(202, "Milk", 30, 50, [Link](2025, 2, 1), groceries);

Product p6 = new Product(301, "Jeans", 2000, 20, [Link](2024, 9, 1), clothing);

Product p7 = new Product(302, "T-Shirt", 1000, 30, [Link](2024, 8, 15), clothing);

[Link]().addAll([Link](p1, p2, p3));

[Link]().addAll([Link](p4, p5));

[Link]().addAll([Link](p6, p7));

List<Category> categories = [Link](electronics, groceries, clothing);

20. Flatten products

List<Product> allProducts = [Link]()

.flatMap(c -> [Link]().stream())

.collect([Link]());

21. Top 3 most expensive products

List<Product> top3Expensive = [Link]()

.sorted([Link](Product::getPrice).reversed())//or can use


Comparator lambda also

.limit(3)

.collect([Link]());

[Link]("Top 3 expensive products: ");

[Link]([Link]::println);
22. Find newest product (latest manufacture date)

Product newest = [Link]()

.max([Link](Product::getManufactureDate))

.orElseThrow();

[Link]("Newest product: " + newest);

23. Find oldest product (earliest manufacture date)

Product oldest = [Link]()

.min([Link](Product::getManufactureDate))

.orElseThrow();

[Link]("Oldest product: " + oldest);

24. Total inventory value (all categories)

double totalInventory = [Link]()

.mapToDouble(p -> [Link]() * [Link]())

.sum();

[Link]("Total inventory value = " + totalInventory);

25. Products cheaper than 2000 grouped by category

Map<String, List<Product>> cheapProductsByCategory = [Link]()

.filter(p -> [Link]() < 2000)

.collect([Link](p -> [Link]().getName()));

[Link]("Cheap products per category (<2000): ");

[Link]((k,v)-> [Link](k+” “+v));

26. Average quantity per category

Map<String, Double> avgQtyByCategory = [Link]()


.collect([Link](p -> [Link]().getName(),

[Link](Product::getQuantity)));

[Link]("Average quantity per category: " + avgQtyByCategory);

[Link]<T> API

1. filter

Select elements that match a condition.

[Link](p -> [Link]() > 10000)

Input: Stream<Product>

Output: Stream<Product> (only expensive products)

2. map

Transform each element into something else.

[Link](Product::getName)// p -> [Link]()

Input: Stream<Product>

Output: Stream<String>

3. flatMap (map & faltten)

Flatten nested collections into a single stream(suitable for onemany mapping, One
CategoryMany Products)

[Link]().flatMap(c -> [Link]().stream())

Input: Stream<Category>

Output: Stream<Product>

4. sorted

Sort elements.

[Link]([Link](Product::getPrice)) //(p1,p2)->
((Double)[Link]()).compareTo([Link]());

Input: Stream<Product>

Output: Stream<Product> (sorted as per price asc)

5. distinct

Remove duplicates (based on equals/hashCode).


[Link]()

6. limit / skip

Get first N elements or skip N elements.

[Link](3) // top 3

[Link](5) // ignore first 5

7. findFirst / findAny

Short-circuit terminal operations to fetch one element.

[Link]() // deterministic (first element)

[Link]() // non-deterministic (any match, faster in parallel)

Output: Optional<T>

8. min / max

Find min or max based on comparator.

[Link]([Link](Product::getPrice))

[Link]([Link](Product::getManufactureDate))

Output: Optional<T>

9. reduce

Aggregate manually (sum, product, concatenation).

[Link](Product::getPrice).reduce(0.0, Double::sum) //equivalent to sum()

Output: one value (e.g. Double)

10. collect (collect stream elements into some collection | map)

Powerful aggregation into collections or maps.

[Link]([Link]()) // List<Product>

[Link]([Link]()) // Set<Product>

[Link]([Link](Product::getId, Product::getName)) // Map<id,name>

11. groupingBy

Group by a classifier (like SQL GROUP BY).


[Link]([Link](p -> [Link]().getName()))

Output: Map<String, List<Product>>

12. partitioningBy

Special case of grouping (boolean predicate).

[Link]([Link](p -> [Link]() > 1000))

Output: Map<Boolean, List<Product>>

13. counting / averaging / summing

Built-in collectors for statistics

[Link]() //count

[Link](Product::getPrice) //average

[Link](p -> [Link]() * [Link]())

14. joining

Concatenate strings.

[Link](Product::getName)

.collect([Link](", ", "[", "]")) //delimiter , prefix , suffix

Output: [Laptop, Mobile, TV, Rice, Milk]

15. mapping (inside grouping)

Transform values during grouping.

[Link](Product::getName, [Link]())

Output: Map<CategoryName, List<String>>

16. collectingAndThen

Post-process collector result.

[Link](

[Link]([Link](Product::getPrice)),

Optional::get

Example: directly get max element instead of Optional.

17. anyMatch / allMatch / noneMatch

Boolean checks on stream.


[Link](p -> [Link]() > 100000) // true/false

18. mapToInt / mapToDouble – mapper functions

Primitive specialization for performance.

[Link](p -> [Link]() * [Link]()).sum()

Output: primitive values (int, long, double)

19. forEach

Terminal operation.

[Link]([Link]::println);

Common Optional<T> Handling Methods

1. isPresent() / get() (old-school, not recommended for production)

Optional<Product> opt = [Link]()

.filter(p -> [Link]() > 5000)

.findFirst();

if ([Link]()) {

[Link]("Found: " + [Link]().getName());

get() without checking may throw the execption!

2. ifPresent()

Run logic only if value exists.

[Link](p -> [Link]("Found: " + [Link]()));

3. ifPresentOrElse() (Java 9+)

Handle both present & empty cases.

[Link](

p -> [Link]("Found: " + [Link]()),

() -> [Link]("No product found!")

);

4. orElse()

Provide a default if empty.


Product defaultProduct = [Link](new Product(0, "Default", 0.0, 0, null, null));

5. orElseGet()

Like orElse, but lazily computes default (supplier is called only if needed).

Product p = [Link](() -> createDummyProduct());

6. orElseThrow()

Throw supplied exception if empty.

Product p = [Link](() -> new RuntimeException("Product not found"));

7. map()

Transform the value inside the Optional (without unwrapping).

Optional<String> productName = [Link](Product::getName);

[Link]([Link]("Unknown"));

8. filter()

Keep only if condition matches.

[Link](p -> [Link]() > 10)

.ifPresent(p -> [Link]("Sufficient stock: " + [Link]()));

Examples

[Link] first expensive product > 70k

Optional<Product> expensiveOpt = [Link]()

.filter(p -> [Link]() > 70000)

.findFirst();

[Link](p -> [Link]("Expensive: " + p));

2. Use orElse

Product safeProduct = [Link](new Product(0, "Default", 0, 0, null, null));

[Link]("OrElse fallback: " + safeProduct);

3. Use orElseThrow

Product mustExist = [Link](() -> new RuntimeException("No product found


> 70k!"));

[Link]("OrElseThrow result: " + mustExist);


4. Extract just name with map

String productName = [Link](Product::getName).orElse("Unknown");

[Link]("Name: " + productName);

5. Apply filter on Optional

[Link](p -> [Link]() > 2)

.ifPresent(p -> [Link]("Has enough stock: " + p));

6. [Link](); // throws NoSuchElementException if empty

7. Custom Exception

// Custom exception for product not found

[Link](() -> new ProductNotFoundException(“No product found above 1


lakh!”)); // throws custom exception if empty

You might also like