Stream simplifies element calculation;
1. Interface design
Since Java 1.8, the concept of Stream has been put forward, focusing on the encapsulation of the computing power of source data, and supports both sequential and parallel operation modes; still look at the design of the core interface first:
- BaseStream: The basic interface, which declares the core methods of stream management;
- Stream: core interface, which declares the core method of stream operation, other interfaces are adaptations of specified types;
Basic case: Return a sequence stream by specifying the value of the element, the content of the element is a string, and convert it to Long type, and finally calculate the summation result and return it;
System.out.println("sum1="+IntStream.of(1,2,3).sum());
System.out.println("sum2="+Stream.of("1", "2", "3").mapToLong(Long::parseLong).sum());
The entire Stream processing process can be divided into three stages: creating a stream, intermediate operations, and final operations, that is, the result of the summation of multiple element values is finally obtained through stream computing;
2. Create operation
In addition to the creation method provided by Stream, in Java 1.8, many methods of container classes have been extended to provide the ability to transfer collection elements;
- Stream creation
Stream<Integer> intStream = Stream.of(1, 2) ;
- Collection creation
List<String> getList = Arrays.asList("hello","copy") ;
Stream<String> strStream = getList.stream() ;
- Array creation
Double[] getArray = new Double[]{1.1,2.2};
Stream<Double> douStream = Arrays.stream(getArray) ;
The Stream streams created by the above methods are all serial sequences by default, which can be judged by Stream.isParallel
; execute the Stream.parallel
method to convert to a parallel stream;
3. Intermediate operation
Usually, the intermediate operation of Stream can be regarded as a query of the source, and it is a lazy design. The calculation of the source data will only be performed when needed, which is similar to the principle of the view in the database;
The power of Stream is that it provides a wealth of intermediate operations, which greatly simplifies the computational complexity of source data compared to containers such as collections or arrays. The data structure used in the case is as follows;
public class TesStream {
public static void main(String[] args) {
List<User> userList = getUserList () ;
}
private static List<User> getUserList (){
List<User> userList = new ArrayList<>() ;
userList.add(new User(1,"张三","上海")) ;
userList.add(new User(2,"李四","北京")) ;
userList.add(new User(3,"王五","北京")) ;
userList.add(new User(4,"顺六","上海,杭州")) ;
return userList ;
}
}
- filter: filter, output users whose id is greater than 1;
userList.stream().filter(user -> user.getId()>1).forEach(System.out::println);
- map: Map the existing element conversion to the corresponding result, and output the city where the user is located;
userList.stream().map(user -> user.getName()+" 在 "+user.getCity()).forEach(System.out::println);
- peek: traverse the elements, add 1 to each user ID and output;
userList.stream().peek(user -> user.setId(user.getId()+1)).forEach(System.out::println);
- flatMap: data split one-to-many mapping, users are located in multiple cities;
userList.stream().flatMap(user -> Arrays.stream(user.getCity().split(","))).forEach(System.out::println);
- sorted: Specify the sorting of attributes, and output in reverse order according to the user ID;
userList.stream().sorted(Comparator.comparingInt(User::getId).reversed()).forEach(System.out::println);
- distinct: Deduplication, the city where the user is located will be output after deduplication;
userList.stream().map(User::getCity).distinct().forEach(System.out::println);
- skip & limit: interception, the filtered data is skipped, and the first one is intercepted;
userList.stream().filter(user -> user.getId()>1).skip(1).limit(1).forEach(System.out::println);
Compared with the processing logic of collections and arrays before Java 1.8, the Stream stream method simplifies a series of operations such as data modification, search, filtering, sorting, etc. The above only involves foreach traversal for the final method;
Fourth, the final operation
After the Stream stream has performed the final operation, other actions cannot be performed, otherwise a status exception will be reported, indicating that the stream has been operated or closed, and the Stream stream must be re-created if the operation is to be performed again;
- min: minimum value, get the minimum id value of the user;
int min = userList.stream().min(Comparator.comparingInt(User::getId)).get().getId();
- max: maximum value, get the user's maximum id value;
int max = userList.stream().max(Comparator.comparingInt(User::getId)).get().getId();
- sum: Summation, cumulative summation of user IDs;
int sum = userList.stream().mapToInt(User::getId).sum() ;
- count: the total number, the total number of users whose id is less than 2;
long count = userList.stream().filter(user -> user.getId()<2).count();
- foreach: traverse and output users related to Beijing;
userList.stream().filter(user -> "北京".equals(user.getCity())).forEach(System.out::println);
- findAny: Find any element that meets the conditions and get a Beijing user;
User getUser = userList.stream().filter(user -> "北京".equals(user.getCity())).findAny().get();
- findFirst: Get the first element that meets the condition;
User getUser = userList.stream().filter(user -> "北京".equals(user.getCity())).findFirst().get();
- anyMatch: match judgment to judge whether there is a user in Shenzhen;
boolean matchFlag = userList.stream().anyMatch(user -> "深圳".equals(user.getCity()));
- allMatch: All matches, judging that the city of all users is not empty;
boolean matchFlag = userList.stream().allMatch(user -> StrUtil.isNotEmpty(user.getCity()));
- noneMatch: no match at all, the city that judges no user is empty;
boolean matchFlag = userList.stream().noneMatch(user -> StrUtil.isEmpty(user.getCity()));
This is just to demonstrate some simple final methods, mainly involving some statistical and judgment-related capabilities of Stream streams. In some practical business applications, these functions are obviously far from enough;
5. Collect collection
Collector: The core interface of the result collection strategy, which has the ability to accumulate the specified elements into the result container; and provides the implementation class of the Collector interface in the Collectors tool;
- toList: Store the user ID in the List collection;
List<Integer> idList = userList.stream().map(User::getId).collect(Collectors.toList()) ;
- toMap: Store the user ID and Name in the Map collection in the form of Key-Value;
Map<Integer,String> userMap = userList.stream().collect(Collectors.toMap(User::getId,User::getName));
- toSet: Store the user's city in the Set collection;
Set<String> citySet = userList.stream().map(User::getCity).collect(Collectors.toSet());
- counting: the total number of eligible users;
long count = userList.stream().filter(user -> user.getId()>1).collect(Collectors.counting());
- summingInt: sum the result element, the user ID;
Integer sumInt = userList.stream().filter(user -> user.getId()>2).collect(Collectors.summingInt(User::getId)) ;
- minBy: filter the user with the smallest ID in the element
User maxId = userList.stream().collect(Collectors.minBy(Comparator.comparingInt(User::getId))).get() ;
- Joining: link the city where the user is located to a string with the specified separator;
String joinCity = userList.stream().map(User::getCity).collect(Collectors.joining("||"));
- groupingBy: group by condition, group users by city;
Map<String,List<User>> groupCity = userList.stream().collect(Collectors.groupingBy(User::getCity));
In code engineering, there are many logics of collective data calculation, especially in the microservice scenario, the VO data model needs to assemble the data of multiple services, and the assembly process can be greatly simplified through Collector;
$$End$$
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。