Stream
flow generation
Generated by collection
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
Stream<Integer> stream = list .stream();
generated by value
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);
generated by file
Stream<String> lines = Files.lines(Paths.get("data.txt"), Charset.defaultCharset());
Generated by function
- iterator
/**
* 该方法通过迭代器生成无限流,需要limit方法进行截断
* iterate: 内为迭代方法,即生成流的规则
* limit: 参数为生成的数量
*/
Stream<Integer> stream = Stream.iterate(0, n -> n + 2).limit(5);
- generator
/**
* 该方法通过迭代器生成无限流,需要limit方法进行截断
* generate: 内为生成器方法,即生成流的规则
* limit: 参数为生成的数量
*/
Stream<Double> stream = Stream.generate(Math::random).limit(5);
type of flow
Stream, IntStream, DoubleStream, LongStream, the four types of streams are all inherited from BaseStream, where Stream represents the stream of reference type, and the four types can be converted by mapToObj, mapToInt, mapToDouble, mapToLong.
operation type
- Intermediate operation
A stream can be followed by zero or more intermediate operations. Its purpose is mainly to open the stream, do some level of data mapping/filtering, and then return a new stream for use by the next operation. This type of operation is inert. Just calling this type of method does not actually start the traversal of the stream. The real traversal needs to wait until the terminal operation. Common intermediate operations include filter, map, etc. that will be introduced below.
- terminal operation
A stream has and can only have one terminal operation. When this operation is executed, the stream is closed and cannot be operated any more. Therefore, a stream can only be traversed once. If you want to traverse it, you need to generate the stream through the source data. The execution of the terminal operation will actually start the traversal of the stream.
method
filter
- filter
- The parameter is a condition, and returns all elements where the condition is true
- Intermediate operation
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
Stream stream = list.stream().filter(i -> i > 3);
stream.forEach(System.out::println);
result
4
5
6
Process finished with exit code 0
distinct
- Deduplication
- Intermediate operation
List<Integer> list = Arrays.asList(1, 1, 2, 3, 3, 4);
Stream stream = list.stream().distinct();
stream.forEach(System.out::println);
result
1
2
3
4
sorted
- to sort
- Intermediate operation
List<String> list = Arrays.asList("java", "python", "go");
Stream stream;
//自然升序
stream = list.stream().sorted();
stream.forEach(System.out::println);
System.out.println("====================");
//自然降序
stream = list.stream().sorted(Comparator.reverseOrder());
stream.forEach(System.out::println);
System.out.println("====================");
//对象升序
stream = list.stream().sorted(Comparator.comparing(String::length));
stream.forEach(System.out::println);
System.out.println("====================");
//对象降序
stream = list.stream().sorted(Comparator.comparing(String::length).reversed());
stream.forEach(System.out::println);
System.out.println("====================");
//自定义排序规则
stream = list.stream().sorted(Comparator.comparing(s -> s.charAt(1)));
stream.forEach(System.out::println);
System.out.println("====================");
//多规则排序
stream = list.stream().sorted(Comparator.comparing(String::length).thenComparing(String::hashCode));
stream.forEach(System.out::println);
result
go
java
python
====================
python
java
go
====================
go
java
python
====================
python
java
go
====================
java
go
python
====================
go
java
python
issueWhile
- cycle retention
- Keep all elements before the first element that does not meet the condition, so if the condition in the example is changed to i>4, no element will be kept, and the return will be empty
- Intermediate operation
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> stream = list.stream().takeWhile(i -> (i < 4));
stream.forEach(System.out::println);
result
1
2
3
dropWhile
- cycle discard
- Discard all elements before the first element that does not meet the condition, so if the condition in the example is changed to i>4, no element will be discarded, and the return is from 1 to 5
- Intermediate operation
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> stream = list.stream().dropWhile(i -> (i < 4));
stream.forEach(System.out::println);
result
4
5
peek
- traverse
- peek is an intermediate operation, and forEach is a terminal operation. The only difference between the two is that peek is often used to assist modulation
- Intermediate operation
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
list.stream()
.peek(System.out::println)
.dropWhile(i -> (i < 4))
.forEach(System.out::println);
result
1
2
3
4
4
5
5
limit
- front intercept
- The parameter is the number of elements to return
- Intermediate operation
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
Stream stream = list.stream().limit(3);
stream.forEach(System.out::println);
result
1
2
3
skip
- After interception
- The parameter is the number of elements to skip
- Intermediate operation
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
Stream stream = list.stream().skip(2);
stream.forEach(System.out::println);
result
3
4
5
6
map
- map
- Maps an element to another element via the method in the argument
- Intermediate operation
List<String> list = Arrays.asList("java", "python", "go");
Stream stream = list.stream().map(String::length);
stream.forEach(System.out::println);
result
4
6
2
flatMap
- flat flow
- Convert each value into a stream, which can be understood as converting a multi-layer structure into a single-layer stream
- Intermediate operation
/**
* 经过map之后的类型为 Stream<String[]>,可以认为是两层结构
* 经过flatMap后将map结果的流转换成扁平的单层流
*/
List<String> list = Arrays.asList("java 17", "python 3.9", "go 1.18");
Stream stream = list.stream()
.map(w -> w.split(" "))
.flatMap(Arrays::stream);
stream.forEach(System.out::println);
result
java
17
python
3.9
go
1.18
allMatch
- matches all elements
- The return value is boolean, if the parameter is true for all elements, it returns true, otherwise it returns false; the meaning is opposite to noneMatch
- Intermediate operation
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
if (list.stream().allMatch(i -> i > 4)) {
System.out.println("所有元素值都大于4");
} else {
System.out.println("不是所有元素值都大于4");
}
result
不是所有元素值都大于4
anyMatch
- matches one of the elements
- The return value is boolean, if the parameter is true for any element, it returns true, otherwise it returns false
- Intermediate operation
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
if (list.stream().anyMatch(i -> i > 4)) {
System.out.println("存在大于4的元素");
} else {
System.out.println("不存在大于4的元素");
}
result
存在大于4的元素
noneMatch
- all elements do not match
- The return value is boolean, if the parameter is false for all elements, it returns true, otherwise it returns false; the opposite meaning of allMatch
- Intermediate operation
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
if (list.stream().noneMatch(i -> i > 4)) {
System.out.println("不存在大于4的元素");
} else {
System.out.println("存在大于4的元素");
}
result
存在大于4的元素
count
- Number of statistical elements
- Returns the number of elements in the stream, and the return value is long
- terminal operation
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
long count = list.stream().count();
System.out.println(count);
result
5
findFirst
- find the first
- Returns the first element, usually used with filter, returns the first element that satisfies the filter condition, and the return type is Optional
- terminal operation
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Optional result = list.stream().filter(i -> i > 3).findFirst();
System.out.println(result.orElse(-1));
result
4
findAny
- find a random one
- Return a random element, usually used with filter, return a random element that satisfies the filter condition, the return type is Optional, in the case of less data and serial, generally return the first one, which is consistent with the return of findFirst; if the data is relatively small When multiple or parallel, the returned elements are random, and findAny is more efficient than findFirst
- terminal operation
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Optional result = list.stream().filter(i -> i > 3).findAny();
System.out.println(result.orElse(-1));
result
4
reduce
- Reduction calculation (actually, I don’t know how to translate it well)
- The first parameter is the initial value, and the second parameter is the operation, which is equivalent to adding the initial value to the head of the stream, and then calling the method of the second parameter continuously. It is better to understand the operation of accumulation and multiplication
- terminal operation
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
int sum = list.stream()
.reduce(0, Integer::sum);
int product = list.stream()
.reduce(1, (a, b)->a * b);
System.out.println(sum);
System.out.println(product);
result
15
120
max
- maximum value
- Return the largest element, the parameter is the comparison method, usually the compare method
- terminal operation
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> max = list.stream()
.max(Integer::compareTo);
System.out.println(max.orElse(-1));
result
5
min
- minimum value
- Return the smallest element, the parameter is the comparison method, usually the compare method
- terminal operation
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> min = list.stream()
.min(Integer::compareTo);
System.out.println(min.orElse(-1));
result
1
foreach
- traverse
- terminal operation
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
list.forEach(System.out::println);
result
1
2
3
4
5
collect
- return collection
- terminal operation
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> intList = list.stream()
.collect(Collectors.toList());
Through the Collectors.toXXX() method, it can be converted to other collection types, such as:
toList: convert to List
toSet: convert to Set
toMap: convert to Map
joining
- stitching
- Join elements together by parameters
- collect operation
List<String> list = Arrays.asList("java 17", "python 3.9", "go 1.18");
String str = list.stream()
.collect(Collectors.joining(";"));
System.out.println(str);
result
java 17;python 3.9;go 1.18
groupingBy
- group
- Group elements according to parameter rules, grouping methods can be nested and customized
- collect operation
//单层分组
List<String> list = Arrays.asList("java", "python", "go", "delphi", "groovy", "perl");
Map<Integer, List<String>> map = list.stream()
.collect(Collectors.groupingBy(String::length));
System.out.println(map);
System.out.println("===================");
// //两层分组,二层为自定义条件
Map<Integer, Map<String, List<String>>> map2 = list.stream()
.collect(Collectors.groupingBy(String::length,
Collectors.groupingBy(s -> s.charAt(0) + "")));
System.out.println(map2);
result
{
2=[go], 4=[java, perl], 6=[python, delphi, groovy]}
===================
{
2={
g=[go]}, 4={
p=[perl], j=[java]}, 6={
p=[python], d=[delphi], g=[groovy]}}
partitioningBy
- group
- The parameters are returned as boolean, grouped according to the boolean value, and can be divided into two groups at most
- collect operation
List<String> list = Arrays.asList("java", "python", "go", "delphi", "groovy", "perl");
Map<Boolean, List<String>> map = list.stream()
.collect(Collectors.partitioningBy(s -> s.length() > 4));
System.out.println(map);
result
{
false=[java, go, perl], true=[python, delphi, groovy]}