Stream is an abstract concept of processing sets in Java 8, which can perform complex operations such as finding, filtering and mapping. stay
Operation API
The Stream API provides an efficient and easy-to-use way to process data:
- It is not a data structure and will not save data;
- If the data source is not modified, the operation result will be saved to the result object;
- Inert evaluation: the intermediate processing process is only an operation record and will not be executed immediately; Instead, the actual calculation will not be carried out until the operation is terminated;
Function parameters in the interface can pass Lambd expressions or class functions with the same signature (ClsName::funName style is required at this time). Take groupingBy as an example:
// When the stream element is a string, the following two are equivalent groupingBy(String::length); groupingBy(z->{return z.length;});
classification
Operation interfaces can be divided into:
- Stateless class: processing operations are not affected by previous elements;
- Stateful class: the operation will not proceed to the next step until all elements are obtained;
- Non short circuit operation: all elements must be processed to get the final result;
- Short circuit operation: find the qualified elements to get the final result;
Stream API | ||
Intermediate operation | Stateless |
|
Stateful |
| |
End operation | Non short circuit operation |
|
Short circuit operation |
|
Interface description
mapping
-
map: receive the elements in the source and return the elements in the result set;
-
flatMap: similar to map, but when the element is stream, synthesize multiple streams into one and return the result.
List<String> lstAll = Arrays.asList("hello", "world"); // Output two numbers: [h, e, l, l, o] and [w, o, r, l, d] lstAll.stream() .map(s->{return s.split("");}) .forEach(s->{ System.out.println(Arrays.toString(s)); }); // Output each character: h\n e\n... lstAll.stream() .flatMap(s->{return Stream.of(s.split(""));}) .forEach(System.out::println);
Create stream
Most collections in Java 8 have a stream() interface, which can directly obtain the stream.
Collection.stream
Collections in Java inherit or implement collection Stream () interface:
Arrays.asList(3, 5, 7, 16, 18) .stream() .filter(z->{return z%2==0;}) .forEach(System.out::println); // Output even
Arrays.stream
Via arrays Stream() generates an array of streams:
Integer[] array = new Integer[]{3, 4, 8, 16, 19}; long count = Arrays.stream(array) .filter(i -> i > 10) .count();
Stream.of
Through stream Of() can turn a specified element (single, or multiple) into a stream:
List<Integer> lstAll = Stream.of(1, 3, 5, 7) .map(z -> { return z * 2; }) .collect(Collectors.toList());
Infinite flow
For infinite flow, you need to limit the length of the final flow through limit.
Stream.generate
Through stream Generate() generates a stream of infinite length (according to the specified rules):
Stream.generate(new Random()::nextInt) .limit(5).forEach(System.out::println); // Output 5 random numbers
Stream.iterate
Through stream Iterate() can also generate a stream of infinite length, which accepts a parameter and a generating function:
Set<Integer> setAll = Stream.iterate(1, n->{return n*2;}) .limit(5) .collect(Collectors.toSet()); System.out.println(setAll);
Collectors
Collect elements according to different strategies. For example, the simplest and most common method is to load elements into variable containers such as Map, Set and List.
Merge to set
toXXX
- toCollection: place all the elements in the stream into a collection (the specific collection type is determined by parameters, such as Collectors.toCollection(LinkedList::new));
- toList: converted to List and returned;
- toSet: convert to Set and return;
- toMap: convert to Map and return;
List<String> lstTest = Arrays.asList("a123", "a456", "b789", "b890"); lstTest.stream() .collect(Collectors.toMap( e -> e.substring(0, 1), // Key e -> e, // value (a, b) -> b, // Replace the processing method when the key is repeated HashMap::new) // Optional, use map type ) .forEach((k, v) -> System.out.println(k + "=" + v));
mapping
It is equivalent to converting to a map and then to a set: Map (XX) Colcollect(Collectors.toXX())
lstTest.stream().collect( Collectors.mapping( Integer::valueOf, // map mode Collectors.toList()));
grouping
groupingBy
Generate a Collector with grouping function: the default is to generate HashMap, and the elements in the same group are ArrayList.
List<String> lstTest = Arrays.asList("a123", "a4561", "b789", "b8901"); lstTest.stream().collect( Collectors.groupingBy( String::length, // Grouping mode HashMap::new, // Result set Map type Collectors.toSet())) // Value (elements in the same group) collection type in Map .forEach((k, v) -> System.out.println(k + "=" + v));
partitioningBy
The elements in the flow are divided into two parts according to the results of the given verification rules: those that meet the conditions and those that do not meet the conditions; The key values of Map are true and false.
List<String> lstTest = Arrays.asList("a123", "a4561", "b789", "b8901"); lstTest.stream().collect( Collectors.partitioningBy( e -> e.length() > 4, // Classification method Collectors.toSet())) // The Value (elements in the same group) collection type in the Map. The default is List .forEach((k, v) -> System.out.println(k + "=" + v));
Calculation and statistics
- Counting: counting
- minBy/MaxBy: obtain the Optional result of min / max value;
- summingInt/summingLong/summingDouble: sum;
- averagingInt/averagingLong/averagingDouble: average;
reduce
reducing is a collector (operation), which can be used in multi-layer streams, downstream data packets or partitions. count(),max(),min(),sum() are predefined collectors.
Comparator<Person> funHeight = Comparator.comparingInt(Person::getHeight); Map<City, Optional<Person>> tallestByCity = personList.stream(). collect(groupingBy( Person::getCity, reducing(BinaryOperator.maxBy(funHeight))));
Get the highest in each city
collectingAndThen
After merging the results, the results will be further processed.
lstTest.stream().collect( Collectors.collectingAndThen( Collectors.groupingBy(String::length), z -> z.size()));
After grouping, get the number of groups (there are several groups in total).