Java 8 has been out for so long. How about the Stream API?

Java 8 introduces a new Stream API, which can process data in a declarative way, which greatly facilitates the collectio...
Background introduction
Creation of Stream object
Use the collect method to convert a List into a map
Define objects that contain subordinate permissions
Define the method to get the tree structure
Set child permissions for each permission

Java 8 introduces a new Stream API, which can process data in a declarative way, which greatly facilitates the collection operation, so that we can use less code to realize more complex logic. This paper mainly introduces some commonly used stream APIs.

What is Stream?

A Stream is a queue of elements from a data source that supports aggregation operations.

  • Data source: the data source of the Stream. Construct the data source of the Stream object. For example, construct the Stream object through a List, which is the data source;
  • Aggregation operation: the operation that causes the Stream object to return the specified rule data after processing the Stream object is called aggregation operation. For example, filter, map, limit, sorted, etc. are aggregation operations.
Stream aggregation operation

Background introduction

This article will take the UmsPermission object in mall as an example to introduce the common operations of Stream API. UmsPermission is a permission object, which is mainly divided into three types: directory, menu and button. The object definition is as follows.

public class UmsPermission implements Serializable { private Long id; @ApiModelProperty(value = "Parent permission id") private Long pid; @ApiModelProperty(value = "name") private String name; @ApiModelProperty(value = "Permission value") private String value; @ApiModelProperty(value = "Icon") private String icon; @ApiModelProperty(value = "Permission type: 0->catalogue one->Menu; two->Button (interface binding permission)") private Integer type; @ApiModelProperty(value = "Front end resource path") private String uri; @ApiModelProperty(value = "Enable status; 0->Disable; one->Enable") private Integer status; @ApiModelProperty(value = "Creation time") private Date createTime; @ApiModelProperty(value = "sort") private Integer sort; private static final long serialVersionUID = 1L; //Omit all getter and setter methods }

Creation of Stream object

Stream objects are divided into two types: a serial stream object and a parallel stream object.

// permissionList refers to the list of all permissions // Create a serial stream object for the collection Stream<UmsPermission> stream = permissionList.stream(); // Create a parallel flow object for the collection tream<UmsPermission> parallelStream = permissionList.parallelStream();

filter

Filter the elements in the Stream, and return the corresponding elements when the setting condition returns true.

// Get permission with permission type of directory List<UmsPermission> dirList = permissionList.stream() .filter(permission -> permission.getType() == 0) .collect(Collectors.toList());

map

Obtained after converting the elements in the Stream. For example, you can convert the UmsPermission object to a Long object. We often need to extract the IDs of some objects, and then query other objects according to these IDs. This method can be used at this time.

// A collection of IDs that get all permissions List<Long> idList = permissionList.stream() .map(permission -> permission.getId()) .collect(Collectors.toList());

limit

Gets the specified number of elements from the Stream.

// Get the collection composed of the first five permission objects List<UmsPermission> firstFiveList = permissionList.stream() .limit(5) .collect(Collectors.toList());

count

Only get the number of elements in the Stream.

// count operation: get the number of all directory permissions long dirPermissionCount = permissionList.stream() .filter(permission -> permission.getType() == 0) .count();

sorted

Sorts the elements in the Stream according to the specified rules.

// Sort all permissions in the order of directory, menu and button List<UmsPermission> sortedList = permissionList.stream() .sorted((permission1,permission2)->) .collect(Collectors.toList());

skip

Skip the specified number of elements in the Stream and get the following elements.

// Skip the first five elements and return to the following List<UmsPermission> skipList = permissionList.stream() .skip(5) .collect(Collectors.toList());

Use the collect method to convert a List into a map

Sometimes we need to repeatedly query the objects in the List according to the id. we can first convert the List into a map structure with id as the key, and then obtain the objects through map.get(id).

// Convert the permission list to map with id as key and permission object as value Map<Long, UmsPermission> permissionMap = permissionList.stream() .collect(Collectors.toMap(permission -> permission.getId(), permission -> permission));
application

We often need to return tree data. For example, the first level of permissions here is directory permissions. There are menu permissions under directory permissions and button permissions under menu permissions. If we want to return a collection containing directory permissions, menu permissions are nested under directory permissions, and button permissions are nested under menu permissions. Using Stream API can easily solve this problem.

Note: here, the upper and lower levels of permissions are associated by pid. pid refers to the id of the upper level permission, and the id of the top-level permission is 0.

Define objects that contain subordinate permissions

Inherited from the UmsPermission object, which adds a children attribute to store subordinate permissions.

/** * Created by macro on 2018/9/30. */ public class UmsPermissionNode extends UmsPermission { private List<UmsPermissionNode> children; public List<UmsPermissionNode> getChildren() { return children; } public void setChildren(List<UmsPermissionNode> children) { this.children = children; } }

Define the method to get the tree structure

We first filter out the top-level permissions with pid 0, and then set its child permissions for each top-level permission. The main purpose of the covert method is to find the child permissions of the corresponding permissions from all permissions.

@Override public List<UmsPermissionNode> treeList() { List<UmsPermission> permissionList = permissionMapper.selectByExample(new UmsPermissionExample()); List<UmsPermissionNode> result = permissionList.stream() .filter(permission -> permission.getPid().equals(0L)) .map(permission -> covert(permission, permissionList)).collect(Collectors.toList()); return result; }

Set child permissions for each permission

Here, we use the filter operation to filter out the child permissions of each permission. Since there may be child permissions under the child permissions, we use recursion to solve this problem. However, when the recursive operation stops, the recursive calling method is put into the map operation. When there is no child permission, the map operation under the filter will not be executed again, so as to stop the recursion.

/** * Convert permissions to permission objects with children * When the child permission cannot be found, the map operation will not call covert recursively */ private UmsPermissionNode covert(UmsPermission permission, List<UmsPermission> permissionList) { UmsPermissionNode node = new UmsPermissionNode(); BeanUtils.copyProperties(permission, node); List<UmsPermissionNode> children = permissionList.stream() .filter(subPermission -> subPermission.getPid().equals(permission.getId())) .map(subPermission -> covert(subPermission, permissionList)).collect(Collectors.toList()); node.setChildren(children); return node; }

6 November 2021, 03:59 | Views: 8702

Add new comment

For adding a comment, please log in
or create account

0 comments