Mastering flatMap in Java: Real-World Spring Boot 3 Examples

This article explains the powerful flatMap operator in Java streams, covering basic usage, Optional handling, replacing nested loops, API response flattening, combining with filter, reactive programming, and a comprehensive end‑to‑end example, all illustrated with Spring Boot 3 code snippets.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Mastering flatMap in Java: Real-World Spring Boot 3 Examples

1. Introduction

flatMap is a powerful tool in functional programming that transcends traditional iteration and nested loops. By performing a "map‑then‑flatten" operation, it elegantly handles nested data, collection transformations, and asynchronous streams, enabling clearer and more expressive conversion logic.

2. Practical Cases

2.1 flatMap Basic Usage

Suppose you have a List<List<String>> and want a single list of all strings. Most developers would use flatMap as shown below:

List<List<String>> names = List.of(
  List.of("张三", "李四"),
  List.of("曹查理", "大卫"),
  List.of("女娲", "Jerry")
);
// Flatten the nested list into a single list of strings
List<String> flattened = names.stream()
    .flatMap(List::stream)
    .toList();
System.out.println(flattened);

Output:

[张三, 李四, 曹查理, 大卫, 女娲, Jerry]

The result is a Stream<String>, not a Stream<List<String>>.

2.2 flatMap with Optional

When dealing with Optional, nested Optional<Optional<T>> structures can appear. flatMap unwraps the nesting:

public static void main(String[] args) {
  Optional<String> nameOpt = Optional.of("Spring Boot3实战案例200讲");
  Optional<Optional<String>> result = nameOpt
      .map(FlatMapDemo2::toUpperCase); // ❌ nested Optional
  System.out.println(result);
}
public static Optional<String> toUpperCase(String s) {
  if (s == null || s.isEmpty()) {
    return Optional.empty();
  }
  return Optional.of(s.toLowerCase());
}

Output:

Optional[Optional[spring boot3实战案例200讲]]

Using flatMap eliminates the nesting:

Optional<String> nameOpt = Optional.of("Spring Boot3实战案例200讲");
Optional<String> result = nameOpt.flatMap(FlatMapDemo2::toUpperCase);
System.err.println(result);

Output:

Optional[spring boot3实战案例200讲]

2.3 Replacing Nested Loops

flatMap can replace nested loops, such as generating a Cartesian product of products and colors:

List<String> products = List.of("IPad", "IPhone", "Book");
List<String> colors = List.of("黑色", "白色");
List<String> result = products.stream()
    .flatMap(product -> colors.stream()
        .map(color -> product + " - " + color))
    .collect(Collectors.toList());
result.forEach(System.out::println);

Output:

IPad - 黑色
IPad - 白色
IPhone - 黑色
IPhone - 白色
Book - 黑色
Book - 白色

2.4 flatMap for API Responses

When an API returns lists or optional fields, flatMap can flatten the data without explicit null checks:

public static void main(String[] args) {
  List<User> users = List.of(
      new User("Pack_xg", Arrays.asList("111", "222")),
      new User("pack", Arrays.asList("333")),
      new User("xg", Arrays.asList("444", "555"))
  );
  List<String> result = users.stream()
      .flatMap(user -> user.phones().stream())
      .toList();
  System.out.println(result);
}
public record User(String name, List<String> phones) {}

Output:

[111, 222, 333, 444, 555]

2.5 flatMap + filter

Combining flatMap with filter can extract valid email addresses from nested lists:

List<List<String>> emails = List.of(
    List.of("[email protected]", "www.qq.com"),
    List.of("[email protected]"),
    List.of("xg@", "[email protected]")
);
List<String> result = emails.stream()
    .flatMap(List::stream)
    .filter(email -> email.contains("@") && email.contains("."))
    .toList();
System.out.println(result);

Output:

[[email protected], [email protected], [email protected]]

2.6 flatMap in Reactive Programming

Using Project Reactor, flatMap can expand each element into multiple elements in a reactive stream:

<dependency>
  <groupId>io.projectreactor</groupId>
  <artifactId>reactor-core</artifactId>
  <version>3.7.11</version>
</dependency>

Flux<String> users = Flux.just("Pack_xg", "pack", "xg");
users.flatMap(user -> Flux.just(user.toUpperCase(), user.toLowerCase()))
    .subscribe(System.out::println);

Output:

PACK_XG
pack_xg
PACK
pack
XG
xg

2.7 Comprehensive Example

Flatten a hierarchy of users → orders → products to obtain all product names:

// Records
public record Product(String name) {}
public record Order(List<Product> products) {}
public record User(String name, List<Order> orders) {}

// Data preparation
List<Product> p1 = List.of(new Product("iPhone 15"), new Product("AirPods Pro"));
List<Product> p2 = List.of(new Product("MacBook Pro"));
List<Order> o1 = List.of(new Order(p1), new Order(p2));
User zhangsan = new User("张三", o1);
List<Product> lisiProducts1 = List.of(new Product("iPad Air"), new Product("Apple Watch"));
List<Order> o2 = List.of(new Order(lisiProducts1));
User lisi = new User("李四", o2);
User wangwu = new User("王五", List.of());
List<User> users = List.of(zhangsan, lisi, wangwu);

// Using flatMap
List<String> productNames = users.stream()
    .flatMap(user -> user.orders().stream())
    .flatMap(order -> order.products().stream())
    .map(Product::name)
    .toList();
System.out.println(productNames);

Output:

[iPhone 15, AirPods Pro, MacBook Pro, iPad Air, Apple Watch]

Mastering flatMap not only simplifies code but also changes the way you think about data transformation, eliminating repetitive nested loops.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaSpring BootFunctional programmingStreamsflatMap
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.