如何用Java 8 Stream统计contentType为video的Content元素数量
Great question! Let's break down how to count the number of Content elements where contentType equals "video", building on the topic count code you already have. We'll traverse the nested lists safely and use Stream operations to get the exact count you need.
Step-by-Step Solution
Here's a robust implementation that handles null lists (to avoid NullPointerException) while following the pattern of your existing code:
import java.util.Objects; import java.util.Optional; import java.util.stream.Stream; // Your existing Subject/Unit/Topic/Content class definitions go here int videoContentCount = Optional.ofNullable(subject.getUnits()) .map(List::stream) .orElseGet(Stream::empty) .map(Unit::getTopics) .filter(Objects::nonNull) .flatMap(List::stream) .map(Topic::getContents) .filter(Objects::nonNull) .flatMap(List::stream) .filter(content -> "video".equals(content.getContentType())) .mapToInt(x -> 1) .sum();
Let's walk through each part:
- Safe null handling:
Optional.ofNullable(subject.getUnits())ensures we don't crash if the units list is missing. We either convert it to a stream or use an empty stream as a fallback. - Flatten topics: Unlike your topic count code that sums list sizes, we use
flatMap(List::stream)to turn each list of topics into a stream of individualTopicobjects—this lets us dig deeper into each topic's contents. - Flatten contents: We repeat the flatMap pattern for contents, turning each list of
Contentelements into a stream of individual items. - Filter video content: We keep only elements where
contentTypematches "video" (swap toequalsIgnoreCaseif you need case-insensitive matching). - Count elements:
mapToInt(x ->1).sum()gives us an integer count (use.count()instead if you're okay with alongresult).
Simplified Version (For Consistent Data)
If you're sure none of the nested lists (units, topics, contents) will ever be null, you can simplify the code to match your original topic count structure:
int videoContentCount = subject.getUnits().stream() .map(Unit::getTopics) .flatMap(List::stream) .map(Topic::getContents) .flatMap(List::stream) .filter(content -> "video".equals(content.getContentType())) .mapToInt(x -> 1) .sum();
This cuts out the null checks but risks crashes if any list is missing—only use this if you trust your data consistency.
内容的提问来源于stack exchange,提问作者Vikash Kumar Singh

