Java Stream API Examples in JDK 17

Java Stream API Examples in JDK 17

This article demonstrates practical examples of using Java Stream API with JDK 17. The examples cover grouping, mapping, sorting, and flatMap operations, along with performance comparisons between different approaches.

Environment Setup

  • Operating System: Windows 11
  • JDK Version: 17
  • Spring Framework: 2.6.7

Content Class Imlpementation

The following Content class demonstrates various Stream operations:

package com.example.stream.demo;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONWriter.Feature;

public class Content {
    private final String heading;
    private final String creator;
    private final List<string> categories;
    private final String regionCode;
    private final String state;
    private Integer cost;

    public Integer getCost() {
        return cost;
    }

    public void setCost(Integer cost) {
        this.cost = cost;
    }

    public Content(String heading, String creator, List<string> categories,
            String regionCode, String state) {
        this.heading = heading;
        this.creator = creator;
        this.categories = categories;
        this.regionCode = regionCode;
        this.state = state;
        this.cost = Long.valueOf(Math.round(Math.random()*1000)).intValue();
    }

    public String getHeading() {
        return heading;
    }

    public String getCreator() {
        return creator;
    }

    public List<string> getCategories() {
        return categories;
    }

    public String getRegionCode() {
        return regionCode;
    }

    public String getState() {
        return state;
    }

    public Poem transformToPoem() {
        Poem p = new Poem(heading, creator, categories, regionCode, state);
        if (regionCode.equals("CN")) {
            p.setPrice(999);
            p.setBody("仰天大笑出门去");
        } else {
            p.setPrice(872);
            p.setBody("我辈岂是蓬蒿人");
        }
        return p;
    }
    
    public Stream<string> categoriesStream(){
        return this.getCategories().stream();
    }

    /**
     * Traditional grouping approach using loops - more verbose but more efficient
     */
    private static void groupByRegionAndStateByLoop(List<content> contents) {
        Map<string list="" map="">>> result = new HashMap<>();
        for (Content content : contents) {
            Map<string list="">> stateMap = result.get(content.getRegionCode());
            if (stateMap == null) {
                stateMap = new HashMap<>();
                result.put(content.getRegionCode(), stateMap);
            }
            List<content> list = stateMap.get(content.getState());
            if (list == null) {
                list = new ArrayList<>();
                stateMap.put(content.getState(), list);
            }
            list.add(content);
        }
        result.forEach((rc, map) -> {
            System.out.println("Region Code is:" + rc);
            map.forEach((sc, list) -> {
                System.out.println("    State Code is:" + sc);
                list.forEach((content) -> {
                    System.out.println("        Content heading is:"
                            + content.getHeading() + ", creator is:"
                            + content.getCreator());
                });
            });
        });
    }

    /**
     * Sequential stream grouping with Collectors - convenient but less performant
     */
    private static void groupByRegionAndState(List<content> contents) {
        Map<string list="" map="">>> result = contents.stream()
                .collect(Collectors.groupingBy(Content::getRegionCode,
                        Collectors.groupingBy(Content::getState)));
        result.forEach((rc, map) -> {
            System.out.println("Region Code is:" + rc);
            map.forEach((sc, list) -> {
                System.out.println("    State Code is:" + sc);
                list.forEach((content) -> {
                    System.out.println("        Content heading is:"
                            + content.getHeading() + ", creator is:"
                            + content.getCreator());
                });
            });
        });
    }

    private static void groupByRegion(List<content> contents) {
        Map<string list="">> result = contents.stream()
                .collect(Collectors.groupingBy(Content::getRegionCode));
        System.out.println(JSON.toJSONString(result, Feature.PrettyFormat));
    }
    
    /**
     * Parallel stream grouping - more performant than sequential streams
     * Implementation is simple - just change stream() to parallelStream()
     */
    private static void groupByRegionAndStateParallel(List<content> contents) {
        Map<string list="" map="">>> result = contents
                .parallelStream().collect(Collectors.groupingBy(Content::getRegionCode,
                        Collectors.groupingBy(Content::getState)));
        result.forEach((rc, map) -> {
            System.out.println("Region Code is:" + rc);
            map.forEach((sc, list) -> {
                System.out.println("    State Code is:" + sc);
                list.forEach((content) -> {
                    System.out.println("        Content heading is:"
                            + content.getHeading() + ", creator is:"
                            + content.getCreator());
                });
            });
        });
    }
    
    private static void transformToPoems(List<content> contents){
        List<poem> poems = contents.stream().map(Content::transformToPoem).toList();
        System.out.println(JSON.toJSONString(poems, Feature.PrettyFormat));
    }
    
    private static void sortByCost(List<content> contents){
        // Descending order
        contents.sort(new Comparator<content>() {
            @Override
            public int compare(Content a, Content b) {
                return a.getCost().compareTo(b.getCost()) * -1;
            }
        });
        System.out.println(JSON.toJSONString(contents, Feature.PrettyFormat));
    }

    public static void main(String[] args) {
        /**
         * Note: The following benchmarks are not scientifically accurate as 
         * printing consumes significant time. For accurate results, 
         * larger datasets should be used.
         */
        
        List<content> contents = new ArrayList<>();
        Content c1 = new Content("Hello World", "Tom", Arrays.asList("Hello", "World", "Tom"), "CN", "GD");
        Content c2 = new Content("Thank you teacher", "Bruce", Arrays.asList("Thank", "you", "teacher", "Bruce"), "CN", "GX");
        contents.add(c1);
        contents.add(c2);
        
        long start = System.currentTimeMillis();
        groupByRegionAndState(contents);
        long end = System.currentTimeMillis();
        System.out.println("Sequential stream grouping time (ms): " + (end - start) + "\n");

        start = System.currentTimeMillis();
        groupByRegionAndStateParallel(contents);
        end = System.currentTimeMillis();
        System.out.println("Parallel stream grouping time (ms): " + (end - start) + "\n");

        start = System.currentTimeMillis();
        groupByRegionAndStateByLoop(contents);
        end = System.currentTimeMillis();
        System.out.println("Traditional grouping time (ms): " + (end - start));
        
        
        start = System.currentTimeMillis();
        transformToPoems(contents);
        end = System.currentTimeMillis();
        System.out.println("Transformation time (ms): " + (end - start));
        
        // Group by region
        groupByRegion(contents);
        
        // Sort by cost
        System.out.println("-----------------------Sorting----------------");
        sortByCost(contents);
        
        // flatMap example
        System.out.println("----------------------FlatMap------------------");
        List<string> allCategories = contents.stream()
            .flatMap(content -> content.getCategories().stream())
            .map(category -> category.toLowerCase())
            .sorted()
            .collect(Collectors.toList());
        System.out.println(JSON.toJSONString(allCategories, Feature.PrettyFormat));
    }
}
</string></content></content></content></poem></content></string></content></string></content></string></content></content></string></string></content></string></string></string></string>

Poem Class Implementation

package com.example.stream.demo;

import java.util.List;

public class Poem extends Content {
    private String body;
    
    public String getBody() {
        return body;
    }

    public void setBody(String body) {
        this.body = body;
    }

    public Poem(String heading, String creator, List<string> categories, String regionCode, String state) {
        super(heading, creator, categories, regionCode, state);
    }
}
</string>

Sample Output

Region Code is:CN
    State Code is:GX
        Content heading is:Thank you teacher, creator is:Bruce
    State Code is:GD
        Content heading is:Hello World, creator is:Tom
Sequential stream grouping time (ms): 13

Region Code is:CN
    State Code is:GX
        Content heading is:Thank you teacher, creator is:Bruce
    State Code is:GD
        Content heading is:Hello World, creator is:Tom
Parallel stream grouping time (ms): 3

Region Code is:CN
    State Code is:GX
        Content heading is:Thank you teacher, creator is:Bruce
    State Code is:GD
        Content heading is:Hello World, creator is:Tom
Traditional grouping time (ms): 1
[
    {
        "creator":"Tom",
        "body":"仰天大笑出门去",
        "regionCode":"CN",
        "price":999,
        "state":"GD",
        "categories":[
            "Hello",
            "World",
            "Tom"
        ],
        "heading":"Hello World"
    },
    {
        "creator":"Bruce",
        "body":"仰天大笑出门去",
        "regionCode":"CN",
        "price":999,
        "state":"GX",
        "categories":[
            "Thank",
            "you",
            "teacher",
            "Bruce"
        ],
        "heading":"Thank you teacher"
    }
]
Transformation time (ms): 159
{
    "CN":[
        {
            "creator":"Tom",
            "regionCode":"CN",
            "price":27,
            "state":"GD",
            "categories":[
                "Hello",
                "World",
                "Tom"
            ],
            "heading":"Hello World"
        },
        {
            "creator":"Bruce",
            "regionCode":"CN",
            "price":570,
            "state":"GX",
            "categories":[
                "Thank",
                "you",
                "teacher",
                "Bruce"
            ],
            "heading":"Thank you teacher"
        }
    ]
}
-----------------------Sorting----------------
[
    {
        "creator":"Bruce",
        "regionCode":"CN",
        "price":570,
        "state":"GX",
        "categories":[
            "Thank",
            "you",
            "teacher",
            "Bruce"
        ],
        "heading":"Thank you teacher"
    },
    {
        "creator":"Tom",
        "regionCode":"CN",
        "price":27,
        "state":"GD",
        "categories":[
            "Hello",
            "World",
            "Tom"
        ],
        "heading":"Hello World"
    }
]
----------------------FlatMap------------------
[
    "bruce",
    "hello",
    "teacher",
    "thank",
    "tom",
    "world",
    "you"
]

Key Points to Note

  1. flatMap Operation: The flatMap operation transforms each element in the stream into a new stream, then flattens these streams into a single stream. This is useful for processing nested collections.
  2. JSON Formatting: The FastJSON2 library is used for prettty-printing JSSON output:
JSON.toJSONString(allCategories, JSONWriter.Feature.PrettyFormat);

FastJSON2 Dependency

To use FastJSON2, add the following dependency to your project:

<dependency>
    <groupId>com.alibaba.fastjson2</groupId>
    <artifactId>fastjson2</artifactId>
    <version>2.0.8</version>
</dependency>

Tags: java-stream-api jdk17 java-lambda java-collectors java-parallel-streams

Posted on Mon, 18 May 2026 08:03:35 +0000 by storyteller