1. Introduction
What can A Stream be used for? For working with collections, the Stream API provides an efficient and easy-to-use way to work with data by manipulating collection data using the Stream API, similar to database queries executed with SQL
Why Java 8 Stream? Because it’s easy why is it easy? Because Lambda expressions greatly improve programming efficiency and program readability, how to manipulate streams? First of all, you have a data source (array, collection, operation will produce new stream object, the original operation flow stream object does not change the usage have ended, this code is not you write a method to execute a method, but the final trigger operation unified executed only when the end of the end of collect, foreach method is a kind of method, See code and results refer to 2 for details. Mapping map, flatMap usage section
2. Specific usage
2.1 create a flow
List<String> List = new ArrayList<>(); Stream<String> listStream = list.stream(); ParallelStream <String> parallelListStream = list.parallelStream(); Integer[] nums = new Integer[] {1, 2, 3, 4, 5}; Stream<Integer> arrStream = Arrays.stream(nums); arrStream.forEach(System.out::println); Stream<Integer> ofStream = stream. of(1, 2, 3, 4, 5); ofStream.forEach(System.out::println); IterateStream = Stream. Iterate (1, (x) -> x + 10). Limit (4); iterateStream.forEach(System.out::println); GenerateStream = Stream. Generate (Math::random).limit(2); generateStream.forEach(System.out::println);Copy the code
2.2 the operation flow
1. The filter
Skip (n) : skip n elements, with limit(n) can achieve paging distinct: Duplicate elements are removed by hashCode() and equals() of the elements in the stream
Stream<Integer> notNullStreamObj = stream. of(1, 2, null, 4, 5, 6, 7, null, 2); Stream<Integer> notNullStream = notNullStreamObj.filter(i -> (null ! = i)); notNullStream.forEach(System.out::println); Stream<Integer> logicStreamObj = stream. of(1, 2, null, 4, 5, 6, 7, null, 2); Stream<Integer> logicStreamObj = stream. of(1, 2, null, 4, 5, 6, 7, null, 2); Stream<Integer> logicStream = logicStreamObj.filter(i -> (i ! = null && i > 5)); logicStream.forEach(System.out::println); Stream<String> strStreamObj = stream.of ("aa"."ab", null, "ac"."bd"."ee"); Stream<String> strStream = strStreamObj.filter(str -> (null ! = str && str.contains("a"))); strStream.forEach(System.out::println); //skip Stream<String> skipStreamObj = stream.of ("aa"."ab", null, "ac"."bd"."ee"); Stream<String> skipStream = skipStreamObj.skip(2); skipStream.forEach(System.out::println); Stream<String> disStreamObj = stream.of ("aa"."ab", null, "ac"."aa"."ab", null, "ee");
Stream<String> disStream = disStreamObj.distinct();
disStream.forEach(System.out::println); // aa ab null ac ee
Copy the code
2. The map
Map: Takes as an argument a function that is applied to each element, mapping it to a new element. FlatMap: Takes a function as an argument, replaces each value in the stream with another stream, and joins all streams into one stream. Peek: This operation is quite similar to map except that map is a Func function that returns a value, while peer fetts elements and sets the Consumer expression. I don’t see any difference. This method is mainly used for debugging, doing something that consumes the object but does not modify it. Do not use it for nothing. The difference between the two maps and flatMaps is that a map maps each element to a new element, unless you filter it. Otherwise, the number of elements will not change. FlatMap is to convert each value in the original stream into another stream, and then merge the streams together. There must be a return value to assemble the new stream
/ / map the element that contains a, replace | note, note that the element or a whole Stream of each element < String > mapStreamObj = Stream. Of ("a,b,c"."a,e,f"."g,h,i");
Stream<String> mapStream = mapStreamObj.map(str -> str.replaceAll(","."|")); mapStream.forEach(System.out::println); / / a | b | a | e | h | | I f c j / / flatMap can put the elements after segmentation, then according to the new elements, new String Stream < String > flatMapStreamObj = Stream. Of ("a,b,c"."a,e,f"."g,h,i");
Stream<String> flatMapStream = flatMapStreamObj.flatMap(str -> {
String[] arr = str.split(",");
Stream<String> result = Arrays.stream(arr);
return result;
});
flatMapStream.forEach(System.out::println); //a b c d e f g h i
System.out.println("1 = = = = = = = = = = =");
Stream<String> peekStreamObj = Stream.of("a,b,c"."a,e,f"."g,h,i");
Stream<String> peekStream = peekStreamObj.peek(e -> System.out.println("Filtered value: " + e))
.map(String::toUpperCase)
.peek(e -> System.out.println("Mapped value: " + e));
System.out.println("2=========== peek code ends, but log not printed");
Set<String> stringSet = peekStream.collect(Collectors.toSet());
System.out.println("3=========== collect The operation is complete and the code log is printed");
stringSet.forEach(System.out::println);
Copy the code
Map Execution result
1=========== 2=========== peek code ends, but the log does not get Filtered Value: A,b,c Mapped Value: A,B,C Filtered value: a,e,f Mapped value: A,E,F Filtered value: g,h,i Mapped value: G, H, I 3 = = = = = = = = = = = collect end operation, code log to print A, B, C, A, E, F, G, H, ICopy the code
3. Sorting
Sorted (Comparator com) : provides a sorted User class. Sorted (Comparator com) : provides a sorted User class
public static class User {
private String name;
private Integer age;
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' + ", age=" + age + '}'; }}Copy the code
Then look at the use of sort
Stream<String> sortStreamObj = stream.of ("a,e,f"."a,d,c"."a,b,i");
Stream<String> sortStream = sortStreamObj.sorted();
sortStream.forEach(System.out::println); //abi adc aef
User u1 = new User("bb", 1);
User u2 = new User("aa", 2);
User u3 = new User("cc", 3);
User u4 = new User("aa", 4);
Set<User> userSet = Sets.newHashSet(u1, u2, u3, u4);
Stream<User> userStream = userSet.stream().sorted(
(obj1, obj2) -> {
if(obj1.getName().equals(obj2.getName())) {//name equals by agereturn obj1.getAge() - obj2.getAge();
}
return obj1.getName().compareTo(obj2.getName());
}
);
userStream.forEach(System.out::println);// u2 u4 u1 u3
Copy the code
Sort Execution result
a,b,i
a,d,c
a,e,f
User{name='aa', age=2}
User{name='aa', age=4}
User{name='bb', age=1}
User{name='cc', age=3}
Copy the code
4. The flow matching
AllMatch: Receives a Predicate function that returns true only if each element in the stream matches the Predicate, or false noneMatch otherwise: Predicate receives a Predicate function, which returns true only if every element in the stream does not satisfy the Predicate, false anyMatch otherwise: Receives a Predicate function, which returns true only if one element in the stream satisfies the Predicate, and false findFirst otherwise: FindAny: any element in the stream count: total number of elements in the stream Max: maximum number of elements in the stream min: minimum number of elements in the stream
List<Integer> numLists = Arrays.asList(3, 4, 5, 6, 10); // All matches -true
boolean allMatch1 = numLists.stream().allMatch(e -> e > 2); //true
System.out.println("allMatch1:"+ allMatch1); // All matches -true
boolean allMatch2 = numLists.stream().allMatch(e -> e > 5); //false
System.out.println("allMatch2:"+ allMatch2); // All of them do not match -true
boolean noneMatch = numLists.stream().noneMatch(e -> e > 20); //true
System.out.println("noneMatch:"+ noneMatch); // Any element that conforms to -true
boolean anyMatch = numLists.stream().anyMatch(e -> e > 4); //true
System.out.println("anyMatch:"+ anyMatch); // Return the first Integer findFirst = numLists.stream().findfirst ().get(); //3 System.out.println("findFirst:"+ findFirst); // Return any Integer findAny = numLists.stream().findany ().get(); System.out.println("findAny:"+ findAny); // Return count long count = numLists.stream().count(); //5 System.out.println("count:"+ count); // Return Max Integer Max = numLists.stream().max(Integer::compareTo).get(); //10 System.out.println(Max: ""+ max); // Return min Integer min = numLists.stream().min(Integer::compareTo).get(); //3 System.out.println("min:" + min);
Copy the code
Matching execution result
AllMatch1:trueAllMatch2:falseNoneMatch:trueAnyMatch:trueFindFirst: 3 findAny: 3 count: 5 Max: 10 min: 3Copy the code
5. Combined operations
Reduce is a combination operation Reduce (BinaryOperator Accumulator). There is no start value and the operation is performed according to the operation rules. When executed for the first time, the first parameter of the accumulator function is the first element in the stream and the second parameter is the second element of the element in the stream. On the second execution, the first argument is the result of the first function operation, and the second argument is the third element in the stream. Get () Reduce (T identity, BinaryOperator Accumulator) contains the initial value. The second is the transform of the first method. The difference this time is that it takes an identity argument, which specifies the initial value of the Stream loop. If Stream is empty, the value is returned directly, specifically: this method does not return Optional
Optional sumResult = Stream.of(1, 2, 3, 4)
.reduce((sum, item) -> {
System.out.println("sum : " + sum);
sum += item;
System.out.println("item: " + item);
System.out.println("sum+ : " + sum);
System.out.println("-- -- -- -- -- -- -- -- --");
return sum;
});
System.out.println("========sumResult: " + sumResult.get());
Integer sumDefineResult = Stream.of(1, 2, 3, 4)
.reduce(100, (sum, item) -> {
System.out.println("sum : " + sum);
sum += item;
System.out.println("item: " + item);
System.out.println("sum+ : " + sum);
System.out.println("-- -- -- -- -- -- -- -- --");
return sum;
});
System.out.println("========sumDefineResult: " + sumDefineResult);
Copy the code
Reduce Execution result
/ / the following are the results / / view the execution results sum: item 1:2 sum + : 3 -- -- -- -- -- -- -- -- -- the sum: 3 item: 3 sum + : 6 -- -- -- -- -- -- -- -- -- the sum: 6 item: 4 sum + : 10 -- -- -- -- -- -- -- -- -- = = = = = = = = sumResult: 10 sum: 100 item: 1 the sum + : 101 -- -- -- -- -- -- -- -- -- the sum: 101 item: sum + 2: 103 -- -- -- -- -- -- -- -- -- the sum: 103 item: 3 sum + : 106 -- -- -- -- -- -- -- -- -- the sum: 106 item: 4 sum + : 110 -- -- -- -- -- -- -- -- -- = = = = = = = = sumDefineResult: 110Copy the code
6. Collect transformation operations
This is a very, very, very basic operation, 9 out of 10 stream operations will use the current operation
Collect (Collectors. ToList ()) conversion List Collect (Collectors. ToSet ()) conversion Set Collectors. ToMap (key, value) Conversion Map. Error Collectors. Joining () join for Mosaic Collectors. GroupingBy (key) to the key for the map key grouping Collectors. PartitioningBy rules (rules) to partition For example, > 5, The map key is true and false
User s1 = new User("aa", 1);
User s2 = new User("bb", 2);
User s3 = new User("cc", 3);
User s4 = new User("dd", 2); List<User> list = Arrays.asList(s1, s2, s3, s4); List list <Integer> ageList = list.stream().map(User::getAge).collect(Collectors. ToList ()); // [1, 2, 3] System.out.println(ageList.toString()); / / tosetSet<Integer> ageSet = list.stream().map(User::getAge).collect(Collectors.toSet()); // [1, 2, 3] System.out.println(ageSet); // Change the key to map. Otherwise, an error message is reported: Map<String, Integer> userMap = list.stream().collect(Collectors. ToMap (User::getName, User::getAge)); // {cc=10, bb=20, aa=10} System.out.println(userMap); // String separator Connection String joinName = list.stream().map(User::getName).collect(Collectors. Joining ()","."(".")")); // (aa,bb,cc) System.out.println(joinName); // Grouping Map<Integer, List<User>> ageMap = list.stream().collect(Collectors. GroupingBy (User::getAge)); // Grouping Map<Integer, List<User>> ageMap = list.stream(). System.out.println(ageMap); Map<Integer, Map<Integer, List<User>>typeAgeMap = list.stream().collect(Collectors.groupingBy(User::getAge, Collectors.groupingBy(User::getAge)));
System.out.println(typeAgeMap); // Divide into two parts,trueSome are older than 2 years,falsePart of the age less than or equal to 2 years old Map < Boolean, List < User > > partMap = List. The stream () collect (Collectors. PartitioningBy (v - > v.g etAge () > 2)); System.out.println(partMap);Copy the code
Collect Execution result
[1, 2, 3, 2]
[1, 2, 3]
{dd=2, cc=3, bb=2, aa=1}
(aa,bb,cc,dd)
{1=[User{name='aa', age=1}], 2=[User{name='bb', age=2}, User{name='dd', age=2}], 3=[User{name='cc', age=3}]}
{1={1=[User{name='aa', age=1}]}, 2={2=[User{name='bb', age=2}, User{name='dd', age=2}]}, 3={3=[User{name='cc', age=3}]}}
{false=[User{name='aa', age=1}, User{name='bb', age=2}, User{name='dd', age=2}], true=[User{name='cc', age=3}]}
Copy the code
The last
You can leave a comment below to discuss what you don’t understand. You can also pay attention to my private letter and ask me. I will answer it after I see it. Also welcome everyone to pay attention to my official account: bright future, Golden Three silver four job-hunting interview season, sorted out more than 1000 nearly 500 pages of PDF documents of Java interview questions, articles will be updated in it, sorted out the information will be placed in it. Thank you for watching, think the article is helpful to you remember to pay attention to me a thumb-up support!