Java 8 Stream API: Practical Guide for PO Processing with Filter, Map, Sorted, Collect, and ParallelStream
This article introduces Java 8 Stream API, explains its functional style similar to SQL, and demonstrates how to process PO objects using filter, map, sorted, forEach, collect, statistics, and parallelStream operations with complete code examples.
Java 8 added the Stream API, a high‑level abstraction that lets developers process collections in a declarative, SQL‑like manner, treating the data as a flow through a pipeline of operations.
The style is analogous to Linux pipelines and is especially useful when handling PO/VO objects rather than simple strings.
Stream Pipeline Overview
+--------------------+ +------+ +------+ +---+ +-------+</code><code>| stream of elements +-----> |filter+-> |sorted+-> |map+-> |collect|</code><code>+--------------------+ +------+ +------+ +---+ +-------+Filter
Filters elements based on a predicate; only those matching the condition pass through.
// Count students whose score is not null</code><code>long count = list.stream().filter(p -> p.getScore() != null).count();Map
Transforms each element into another form, e.g., extracting a list of scores or concatenating names.
// Extract all scores</code><code>List<Double> scoreList = list.stream().map(p -> p.getScore()).collect(Collectors.toList());</code><code>// Join all names with commas</code><code>String nameString = list.stream().map(p -> p.getName()).collect(Collectors.joining(","));Sorted
Orders the stream; the example sorts by score in descending order.
// Sort by score descending</code><code>List<UserPo> sortedList = list.stream()</code><code> .filter(p -> p.getScore() != null)</code><code> .sorted(Comparator.comparing(UserPo::getScore).reversed())</code><code> .collect(Collectors.toList());forEach
Applies an action to each element; here it adds 10 points to every student's score.
// Add 10 points to each student</code><code>sortedList.stream().forEach(p -> p.setScore(p.getScore() + 10));Note: Only operations like map, filter, sorted do not modify the original collection; forEach can change the elements.
Collect
Aggregates results, useful for grouping, converting to lists, or joining strings.
// Group by score</code><code>Map<Double, List<UserPo>> groupByScore = list.stream()</code><code> .filter(p -> p.getScore() != null)</code><code> .collect(Collectors.groupingBy(UserPo::getScore));</code><code>// Convert to list</code><code>List<Double> scores = list.stream().map(UserPo::getScore).collect(Collectors.toList());Statistics
Provides summary statistics such as max, min, sum, and average.
DoubleSummaryStatistics stats = filteredList.stream()</code><code> .mapToDouble(UserPo::getScore)</code><code> .summaryStatistics();</code><code>System.out.println("Max: " + stats.getMax());</code><code>System.out.println("Min: " + stats.getMin());</code><code>System.out.println("Sum: " + stats.getSum());</code><code>System.out.println("Avg: " + stats.getAverage());ParallelStream
Enables parallel processing of streams to leverage multiple CPU cores, but requires careful evaluation of thread‑safety.
// Parallel count of students with a score</code><code>long parallelCount = list.parallelStream()</code><code> .filter(p -> p.getScore() != null)</code><code> .count();Complete Example Code
public class UserPo {</code><code> private String name;</code><code> private Double score;</code><code> // Constructors, getters, setters omitted for brevity</code><code> @Override</code><code> public String toString() {</code><code> return "UserPo{" + "name='" + name + '\'' + ", score=" + score + '}';</code><code> }</code><code>}</code><code></code><code>public class StreamTest {</code><code> public static void main(String[] args) {</code><code> List<UserPo> list = new ArrayList<>();</code><code> list.add(new UserPo("小一", 10.0));</code><code> list.add(new UserPo("小五", 50.0));</code><code> list.add(new UserPo("小六", 60.0));</code><code> list.add(new UserPo("小6", 60.0));</code><code> list.add(new UserPo("小空", null));</code><code> list.add(new UserPo("小九", 90.0));</code><code></code><code> long count = list.stream().filter(p -> p.getScore() != null).count();</code><code> System.out.println("参加考试的学生人数:" + count);</code><code></code><code> List<UserPo> filtered = list.stream()</code><code> .filter(p -> p.getScore() != null)</code><code> .collect(Collectors.toList());</code><code> System.out.println("参加考试的学生信息:");</code><code> filtered.forEach(System.out::println);</code><code></code><code> List<Double> scores = list.stream().map(UserPo::getScore).collect(Collectors.toList());</code><code> System.out.println("所有学生的成绩集合:" + scores);</code><code></code><code> String names = list.stream().map(UserPo::getName).collect(Collectors.joining(","));</code><code> System.out.println("所有学生的姓名字符串:" + names);</code><code></code><code> List<UserPo> sorted = list.stream()</code><code> .filter(p -> p.getScore() != null)</code><code> .sorted(Comparator.comparing(UserPo::getScore).reversed())</code><code> .collect(Collectors.toList());</code><code> System.out.println("所有学生的成绩集合,逆序排序:");</code><code> sorted.forEach(System.out::println);</code><code></code><code> Map<Double, List<UserPo>> groupByScore = list.stream()</code><code> .filter(p -> p.getScore() != null)</code><code> .collect(Collectors.groupingBy(UserPo::getScore));</code><code> groupByScore.forEach((score, users) -></code><code> System.out.println("成绩:" + score + " 人数:" + users.size()));</code><code></code><code> sorted.forEach(p -> p.setScore(p.getScore() + 10));</code><code> System.out.println("及格人数太少,给每个人加10分");</code><code> sorted.forEach(System.out::println);</code><code></code><code> long passCount = sorted.stream().filter(p -> p.getScore() >= 60).count();</code><code> System.out.println("最后及格人数" + passCount);</code><code></code><code> DoubleSummaryStatistics stats = sorted.stream()</code><code> .mapToDouble(UserPo::getScore)</code><code> .summaryStatistics();</code><code> System.out.println("列表中最大的数 : " + stats.getMax());</code><code> System.out.println("列表中最小的数 : " + stats.getMin());</code><code> System.out.println("所有数之和 : " + stats.getSum());</code><code> System.out.println("平均数 : " + stats.getAverage());</code><code></code><code> long parallelCount = list.parallelStream()</code><code> .filter(p -> p.getScore() != null)</code><code> .count();</code><code> System.out.println("并行流处理参加考试的学生人数:" + parallelCount);</code><code> }</code><code>}The tutorial demonstrates how to replace verbose for‑loops with concise Stream operations, improving readability and maintainability when processing collections of PO objects.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
