Code Logo

Room Schedule Merge with flatMap()

Published at22 Apr 2026
Stream API Medium 0 views
Like0

A school festival spreads sessions across several rooms, and each room keeps its own small list of titles. By the end of the day, the event coordinator wants one single ordered program list for the closing summary instead of a nested structure that still separates everything by room.

Each room list may contain normal session names, extra spaces around a name, or even blank strings when a scheduled slot was left unused. The final merged list should preserve room order and the order inside each room, but it should ignore blank entries and trim the remaining titles so the result looks clean.

Your task is to take a List<List<String>> and return one flat List<String> containing the cleaned non-empty titles.

For example, if the input is [[" Intro ", "", "Music"], [], [" Drama "]], the answer should be ["Intro", "Music", "Drama"]. The blank string disappears, the room with no sessions contributes nothing, and the remaining titles keep their natural left-to-right order after trimming.

This is a good medium Stream API challenge because it is doing more than one operation in sequence. You need to flatten nested collections, normalize the text, remove unusable entries, and still preserve the meaningful order of the original schedule. That makes the pipeline longer, but still very readable once you see each step clearly.

Example Input & Output

Example 1
Input
schedules = [[], [" "]]
Output
[]
Explanation

If every entry is empty after trimming, the final result is an empty list.

Example 2
Input
schedules = [["Talk"], ["Workshop", " Q&A "]]
Output
["Talk", "Workshop", "Q&A"]
Explanation

All titles remain in room order after flattening.

Example 3
Input
schedules = [[" Intro ", "", "Music"], [], [" Drama "]]
Output
["Intro", "Music", "Drama"]
Explanation

Nested room lists are flattened, cleaned, and filtered.

Algorithm Flow

Recommendation Algorithm Flow for Room Schedule Merge with flatMap()
Recommendation Algorithm Flow for Room Schedule Merge with flatMap()

Solution Approach

This problem is built for flatMap(). The input is not one stream of titles. It is a stream of room lists, and each room list contains its own stream of titles. To process the whole festival schedule as one sequence, those nested streams need to be flattened into a single stream first.

That is exactly what flatMap(List::stream) does. It takes each inner list and opens it up so all titles can flow through the rest of the pipeline as one continuous sequence.

After flattening, two cleanup steps are needed. First, trim the text so titles like " Intro " become "Intro". Second, remove entries that are empty after trimming, because those represent unused slots rather than real sessions.

A full stream solution often looks like this:

return schedules.stream()
    .flatMap(List::stream)
    .map(String::trim)
    .filter(title -> !title.isEmpty())
    .collect(Collectors.toList());

The order matters here. Flatten first, then clean each title, then filter out the blanks, and finally collect the remaining values into a list. Because Java streams preserve encounter order by default for this kind of pipeline, the final program list still reflects the original room-by-room schedule.

This feels medium because several stream operations need to cooperate, and the input structure is nested rather than flat. But once you understand the role of flatMap(), the rest of the pipeline reads naturally: flatten, clean, filter, collect.

The runtime is O(n) for the total number of title strings processed. The main lesson is that flatMap() is the right tool when each input element contains its own collection and you want one combined output stream.

Best Answers

java - Approach 1
import java.util.List;
import java.util.stream.Collectors;

class Solution {
    public static List<String> mergeSchedules(List<List<String>> schedules) {
        return schedules.stream()
                .flatMap(room -> room.stream())
                .filter(title -> !title.trim().isEmpty())
                .map(String::trim)
                .collect(Collectors.toList());
    }
}