In the article written before this issue, I once introduced to you that Java Stream pipeline flow is used Java API for simplifying the processing of collection class elements. The process of use is divided into three stages. Before starting this article, I think I still need to introduce these three stages to some new friends, as shown in the picture:
The first stage (in the picture Blue): Convert a collection, array, or line text file into a java Stream pipeline stream
Second stage (dotted line part in the figure): Pipeline streaming data processing operation, processing pipeline every element in . The output elements from the previous pipe serve as the input elements for the next pipe.
The third stage (green in the picture): pipeline flow result processing operation, which is the core content of this article.
Before starting to learn, it is still necessary to review an example we told you before:
List<String> nameStrs = Arrays.asList("Monkey", "Lion", "Giraffe","Lemur"); List<String> list = nameStrs.stream() .filter(s -> s.startsWith("L")) .map(String::toUpperCase) .sorted() .collect(toList()); System.out.println(list);
First use the stream() method to convert the string List For the pipeline stream Stream
, and then perform pipeline data processing operations, first use the filter function to filter all strings starting with uppercase L, then convert the strings in the pipeline to uppercase letters toUpperCase, and then call the sorted method to sort. The usage of these APIs has been introduced in previous articles of this article. Lambda expressions and function references are also used.
Finally, use the collect function for result processing and convert the java Stream pipeline stream into a List. The final output of the list is: [LEMUR, LION]
If you do not use the java Stream pipeline flow, think about how many lines of code you need to complete the above function? Back to the topic, this article is going to introduce you to the third stage: what operations can be done on the pipeline stream processing results? Let’s get started!
If we just want to print out the processing results of the Stream pipeline stream instead of performing type conversion, we can use the forEach() method or forEachOrdered() method .
Stream.of("Monkey", "Lion", "Giraffe", "Lemur", "Lion") .parallel() .forEach(System.out::println); Stream.of("Monkey", "Lion", "Giraffe", "Lemur", "Lion") .parallel() .forEachOrdered(System.out::println);
The parallel() function indicates that the elements in the pipeline are processed in parallel instead of serially, so that the processing speed is faster. However, this may cause the later elements in the pipeline flow to be processed first, and the previous elements to be processed later, that is, the order of the elements cannot be guaranteed.
forEachOrdered can be understood from the name, although it may be possible in the data processing order. There is no guarantee, but the forEachOrdered method can ensure that the order in which the elements are output is consistent with the order in which the elements enter the pipeline stream. That is, it looks like the following (the forEach method cannot guarantee this order):
Monkey
Lion
Giraffe
Lemur
Lion
The most common usage of java Stream is: first, convert the collection class into a pipeline stream, second, process the pipeline stream data, and third, convert the pipeline stream processing result into a collection class. Then the collect() method provides us with the function of converting the pipeline stream processing results into a collection class.
Collect the processing results of the Stream through the Collectors.toSet() method and collect all elements into the Set collection.
Set<String> collectToSet = Stream.of( "Monkey", "Lion", "Giraffe", "Lemur", "Lion" ) .collect(Collectors.toSet()); //最终collectToSet 中的元素是:[Monkey, Lion, Giraffe, Lemur],注意Set会去重。
Similarly, elements can be collected into List
using the toList()
collector.
List<String> collectToList = Stream.of( "Monkey", "Lion", "Giraffe", "Lemur", "Lion" ).collect(Collectors.toList()); // 最终collectToList中的元素是: [Monkey, Lion, Giraffe, Lemur, Lion]
The element collection methods introduced above are all dedicated. For example, use Collectors.toSet() to collect a Set type collection; use Collectors.toList() to collect a List type collection. So, is there a more general way to collect data elements to collect data into any Collection interface subtype? Therefore, here is a general way to collect elements. You can collect data elements into any Collection type: that is, by providing a constructor to the required Collection type.
LinkedList<String> collectToCollection = Stream.of( "Monkey", "Lion", "Giraffe", "Lemur", "Lion" ).collect(Collectors.toCollection(LinkedList::new)); //最终collectToCollection中的元素是: [Monkey, Lion, Giraffe, Lemur, Lion]
Note: LinkedList::new is used in the code, which actually calls the constructor of LinkedList to collect elements into Linked List. Of course, you can also use methods such as LinkedHashSet::new
and PriorityQueue::new
to collect data elements into other collection types, which is more versatile.
Collect the processing results of the Stream through the toArray(String[]::new) method and collect all elements into a string array.
String[] toArray = Stream.of( "Monkey", "Lion", "Giraffe", "Lemur", "Lion" ) .toArray(String[]::new); //最终toArray字符串数组中的元素是: [Monkey, Lion, Giraffe, Lemur, Lion]
Use the Collectors.toMap() method to collect data elements into the Map, but a problem arises: whether the elements in the pipeline are used as keys or as value. We used a Function.identity() method, which simply returns a "t -> t" (the input is the lambda expression of the output). In addition, use the pipeline stream processing function distinct()
to ensure the uniqueness of the Map key value.
Map<String, Integer> toMap = Stream.of( "Monkey", "Lion", "Giraffe", "Lemur", "Lion" ) .distinct() .collect(Collectors.toMap( Function.identity(), //元素输入就是输出,作为key s -> (int) s.chars().distinct().count()// 输入元素的不同的字母个数,作为value )); // 最终toMap的结果是: {Monkey=6, Lion=4, Lemur=5, Giraffe=6}
Collectors.groupingBy is used to implement grouping collection of elements. The following code demonstrates how to collect different data elements into different Lists based on the first letter and encapsulate them. for Map.
Map<Character, List<String>> groupingByList = Stream.of( "Monkey", "Lion", "Giraffe", "Lemur", "Lion" ) .collect(Collectors.groupingBy( s -> s.charAt(0) , //根据元素首字母分组,相同的在一组 // counting() // 加上这一行代码可以实现分组统计 )); // 最终groupingByList内的元素: {G=[Giraffe], L=[Lion, Lemur, Lion], M=[Monkey]} //如果加上counting() ,结果是: {G=1, L=3, M=1}
这是该过程的说明:groupingBy第一个参数作为分组条件,第二个参数是子收集器。
boolean containsTwo = IntStream.of(1, 2, 3).anyMatch(i -> i == 2); // 判断管道中是否包含2,结果是: true long nrOfAnimals = Stream.of( "Monkey", "Lion", "Giraffe", "Lemur" ).count(); // 管道中元素数据总计结果nrOfAnimals: 4 int sum = IntStream.of(1, 2, 3).sum(); // 管道中元素数据累加结果sum: 6 OptionalDouble average = IntStream.of(1, 2, 3).average(); //管道中元素数据平均值average: OptionalDouble[2.0] int max = IntStream.of(1, 2, 3).max().orElse(0); //管道中元素数据最大值max: 3 IntSummaryStatistics statistics = IntStream.of(1, 2, 3).summaryStatistics(); // 全面的统计结果statistics: IntSummaryStatistics{count=3, sum=6, min=1, average=2.000000, max=3}
The above is the detailed content of Analyze terminal operation examples in Java Stream API. For more information, please follow other related articles on the PHP Chinese website!