Java 8 Stream API Tutorial with PO Example and Common Operations
This article introduces Java 8's Stream API, explains its pipeline concept similar to SQL and Linux pipes, and demonstrates common operations such as filter, map, sorted, forEach, collect, statistics and parallelStream using a UserPo class with complete runnable code examples.
Java 8 added a new abstraction called Stream, which lets you process data in a declarative way, similar to writing SQL queries against a database.
Streams treat a collection of elements as a flow that passes through a pipeline where you can apply operations like filtering, sorting, mapping, and aggregation.
The style is comparable to Linux pipelines, and the article uses a PO (UserPo) class to illustrate real‑world usage instead of simple String lists.
filter : selects elements that satisfy a predicate. Example:
long count = list.stream().filter(p -> p.getScore() != null).count();map : transforms each element into another form. Examples:
List<Double> scoreList = list.stream().map(p -> p.getScore()).collect(Collectors.toList()); String nameString = list.stream().map(p -> p.getName()).collect(Collectors.joining(","));sorted : orders elements, optionally in reverse order. Example:
List<UserPo> filterList = list.stream()
.filter(p -> p.getScore() != null)
.sorted(Comparator.comparing(UserPo::getScore).reversed())
.collect(Collectors.toList());forEach : performs an action for each element, often used to modify or display data.
filterList.stream().forEach(p -> p.setScore(p.getScore() + 10));collect : aggregates elements, can be used for grouping, converting to a list, or joining into a string. Example grouping by score:
Map<Double, List<UserPo>> groupByScoreMap = list.stream()
.filter(p -> p.getScore() != null)
.collect(Collectors.groupingBy(UserPo::getScore));statistics : provides summary statistics such as max, min, sum, average.
DoubleSummaryStatistics stats = filterList.stream()
.mapToDouble(UserPo::getScore)
.summaryStatistics();parallelStream : enables parallel processing of streams to improve performance, but requires careful consideration of thread safety.
long parallelCount = list.parallelStream()
.filter(p -> p.getScore() != null)
.count();Complete code example (UserPo class and StreamTest main method):
public class UserPo {
private String name;
private Double score;
public UserPo(String name, Double score) {
this.name = name;
this.score = score;
}
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public Double getScore() { return score; }
public void setScore(Double score) { this.score = score; }
@Override
public String toString() {
return "UserPo{name='" + name + "', score=" + score + "}";
}
} public class StreamTest {
public static void main(String[] args) {
List<UserPo> list = new ArrayList<>();
list.add(new UserPo("小一", 10.0));
list.add(new UserPo("小五", 50.0));
list.add(new UserPo("小六", 60.0));
list.add(new UserPo("小6", 60.0));
list.add(new UserPo("小空", null));
list.add(new UserPo("小九", 90.0));
long count = list.stream().filter(p -> p.getScore() != null).count();
System.out.println("参加考试的学生人数:" + count);
List<UserPo> filterList = list.stream()
.filter(p -> p.getScore() != null)
.collect(Collectors.toList());
System.out.println("参加考试的学生信息:");
filterList.forEach(System.out::println);
List<Double> scoreList = list.stream()
.map(UserPo::getScore)
.collect(Collectors.toList());
System.out.println("所有学生的成绩集合:" + scoreList);
String nameString = list.stream()
.map(UserPo::getName)
.collect(Collectors.joining(","));
System.out.println("所有学生的姓名字符串:" + nameString);
filterList = list.stream()
.filter(p -> p.getScore() != null)
.sorted(Comparator.comparing(UserPo::getScore).reversed())
.collect(Collectors.toList());
System.out.println("所有学生的成绩集合,逆序排序:");
filterList.forEach(System.out::println);
Map<Double, List<UserPo>> groupByScoreMap = list.stream()
.filter(p -> p.getScore() != null)
.collect(Collectors.groupingBy(UserPo::getScore));
System.out.println("按学生成绩归集:");
groupByScoreMap.forEach((k, v) -> System.out.println("成绩:" + k + " 人数:" + v.size()));
filterList.forEach(p -> p.setScore(p.getScore() + 10));
System.out.println("及格人数太少,给每个人加10分");
filterList.forEach(System.out::println);
long passCount = filterList.stream().filter(p -> p.getScore() >= 60).count();
System.out.println("最后及格人数" + passCount);
DoubleSummaryStatistics statistics = filterList.stream()
.mapToDouble(UserPo::getScore)
.summaryStatistics();
System.out.println("列表中最大的数 : " + statistics.getMax());
System.out.println("列表中最小的数 : " + statistics.getMin());
System.out.println("所有数之和 : " + statistics.getSum());
System.out.println("平均数 : " + statistics.getAverage());
long parallelCount = list.parallelStream()
.filter(p -> p.getScore() != null)
.count();
System.out.println("并行流处理参加考试的学生人数:" + parallelCount);
}
}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.
Architecture Digest
Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.
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.
