Master Java 8 Stream API: From Basics to Tree Structures
This article introduces Java 8's Stream API, explains core concepts like streams, sources, and aggregation operations, and demonstrates common methods such as filter, map, limit, count, sorted, skip, and collect with practical code examples that build hierarchical permission trees.
Java 8 introduced a brand‑new Stream API that allows declarative data processing, greatly simplifying collection operations with less code.
What Is a Stream?
A Stream is a sequence of elements sourced from a data provider that supports aggregation operations.
Data source: the origin of the stream, e.g., a List used to create a Stream.
Aggregation operation: actions like filter, map, limit, sorted that produce a result based on defined rules.
Stream Aggregation Operations
Background
We use the UmsPermission object from a mall project as an example. It represents a permission with three types: directory, menu, and button.
public class UmsPermission implements Serializable {
private Long id;
private Long pid;
private String name;
private String value;
private String icon;
private Integer type;
private String uri;
private Integer status;
private Date createTime;
private Integer sort;
private static final long serialVersionUID = 1L;
// getters and setters omitted
}Creating Stream Objects
Streams can be sequential or parallel.
// permissionList is the list of all permissions
Stream<UmsPermission> stream = permissionList.stream(); // sequential
Stream<UmsPermission> parallelStream = permissionList.parallelStream(); // parallelfilter
Filters elements that satisfy a predicate.
List<UmsPermission> dirList = permissionList.stream()
.filter(p -> p.getType() == 0)
.collect(Collectors.toList());map
Transforms each element, e.g., extracting IDs.
List<Long> idList = permissionList.stream()
.map(p -> p.getId())
.collect(Collectors.toList());limit
Gets a fixed number of elements.
List<UmsPermission> firstFiveList = permissionList.stream()
.limit(5)
.collect(Collectors.toList());count
Returns the number of elements.
long dirPermissionCount = permissionList.stream()
.filter(p -> p.getType() == 0)
.count();sorted
Sorts elements according to a comparator.
List<UmsPermission> sortedList = permissionList.stream()
.sorted((p1, p2) -> p1.getType().compareTo(p2.getType()))
.collect(Collectors.toList());skip
Skips a given number of elements.
List<UmsPermission> skipList = permissionList.stream()
.skip(5)
.collect(Collectors.toList());Collecting to a Map
Converts a list to a map keyed by ID for fast lookup.
Map<Long, UmsPermission> permissionMap = permissionList.stream()
.collect(Collectors.toMap(UmsPermission::getId, p -> p));Application: Building a Permission Tree
Often we need to return hierarchical data, such as permissions where directories contain menus, which contain buttons. The Stream API makes this easy.
Note: Permissions are linked by pid , where pid is the parent ID and top‑level permissions have pid = 0 .
Define a Node with Children
public class UmsPermissionNode extends UmsPermission {
private List<UmsPermissionNode> children;
public List<UmsPermissionNode> getChildren() { return children; }
public void setChildren(List<UmsPermissionNode> children) { this.children = children; }
}Method to Get the Tree Structure
public List<UmsPermissionNode> treeList() {
List<UmsPermission> permissionList = permissionMapper.selectByExample(new UmsPermissionExample());
List<UmsPermissionNode> result = permissionList.stream()
.filter(p -> p.getPid().equals(0L))
.map(p -> covert(p, permissionList))
.collect(Collectors.toList());
return result;
}Recursive Conversion to Add Children
private UmsPermissionNode covert(UmsPermission permission, List<UmsPermission> permissionList) {
UmsPermissionNode node = new UmsPermissionNode();
BeanUtils.copyProperties(permission, node);
List<UmsPermissionNode> children = permissionList.stream()
.filter(p -> p.getPid().equals(permission.getId()))
.map(p -> covert(p, permissionList))
.collect(Collectors.toList());
node.setChildren(children);
return node;
}Project source code: https://github.com/macrozheng/mall-learning/tree/master/mall-tiny-stream
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.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
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.
