Java8 aggregation operation collect, reduce method detailed

Source: Internet
Author: User
Tags addall

the basic concept of stream is the difference between a stream and a collection: stream does not store its own elements. Elements are stored in the underlying collection or generated as needed. The stream operator does not change the source object. Instead, it returns a new stream that holds the result. 3. Stream operations can be deferred, which means they wait until the result is needed. The basic process of stream operation can be attributed to 3 parts: creating a stream. In one or more operations, converts the specified stream to an intermediate operation of another stream. A result is produced by terminating the (terminal) method.   This action forces the delay operation to occur immediately before the stream can no longer be used.    The intermediate operations are filter (), distinct (), sorted (), map (), FlatMap (), etc., which are generally collated (filtered, sorted, matched, extracted, etc.) of the data set. The termination method is often done with data processing in the dataset, such as foreach (), Allmatch (), AnyMatch (), Findany (), FindFirst (), and the methods of the numeric calculation classes are sum, max, Min, average, and so on. The termination method can also be the processing of collections, such as reduce (), collect (), and so on. The reduce () method is typically processed to produce a new dataset each time, and the Collect () method is updated on the basis of the original dataset, and no new datasets are generated during the process. Listnums= Arrays.aslist (1, 3,NULL, 8, 7, 8, 13, 10); Nums.stream (). Filter (numNum! =NULL). Distinct (). ForEach (System.out::p rintln); The above code is implemented to filter null values and go to heavy, traverse the results, the implementation is concise and clear. The use of traditional methods is relatively cumbersome. In addition, where foreach is the terminating action method , there is no action if there is no code above the method. The use of filter, map, ForEach, Findany and other methods is relatively simple, omitted here. Here are the powerful aggregation operations, which are divided into two main types: variable aggregation: The accumulation of input elements into a mutable container, such as collection or StringBuilder; other aggregations: Remove the mutable aggregations, and the rest, generally not by repeatedly modifying a mutable object, This is done by taking the previous aggregation result as the next entry. such as reduce,count,allmatch; aggregation operations reduce stream.reduce, which returns a single result value, and the reduce operation always creates a new value for each element processed. Common methods are average, sum, Min, Max, Count, and can be implemented using the reduce method. This article mainly introduces the reduce method: T reduce (t identity, Binaryoperatoraccumulator) identity: It allows the user to provide an initial value for the loop calculation. Accumulator: The calculated accumulator, whose method signature is apply (T t,u U), the first parameter T in the reduce method is the return value of the last function calculation, the second parameter U is the element in the stream, this function calculates these two values to apply, The resulting and assigned value is assigned to the first parameter of the next execution of this method. A bit of a look around the code:intValue = Stream.of (1, 2, 3, 4). Reduce (sum, item), Sum +item); Assert.assertsame (Value,110);/*or use a method reference*/value= Stream.of (1, 2, 3, 4). Reduce (100, integer::sum); In this example 100 is the calculation of the initial value, each time the addition of the calculated value will be passed to the next calculation of the first parameter. Reduce also has two other overloaded methods: Optionalreduce (Binaryoperatoraccumulator): As defined above, no initial value is computed, so he returns a optional. u Reduce (U identity, bifunction<u, huh? U= ""Super= "" >Accumulator, Binaryoperator combiner): Almost identical to the reduce method of the previous two parameters, You just have to notice that Binaryoperator actually implements the Bifunction and Binaryoperator two interfaces. Collect results collect when you're done with the flow, you usually just want to look at the results instead of aggregating them into a single value. First look at the basic method of collect, which accepts three parameters: R Collect (Suppliersupplier, Biconsumer<r, huh? T= ""Super= "" >accumulator, biconsumer<r,r>combiner) Supplier: A way to create an instance of a target type. Accumulator: A method that adds an element to the target. Combiner: A method that combines multiple results from an intermediate state (which is used concurrently). Then look at the code: Streamstream= Stream.of (1, 2, 3, 4). Filter (P, p > 2); Listresult= Stream.collect (()NewArraylist<> (), (list, item), List.add (item), (one,One.addall (both));/*or use a method reference*/result= Stream.collect (ArrayList::New, List::add, list::addall); This example is to filter elements greater than 2 and to collect the remaining results into a new list. The first method generates a new ArrayList; the first parameter in the second method is the ArrayList object that was previously generated, and the second parameter is the element contained in the stream, which is the addition of the elements in the stream to the ArrayList object. The second method is called repeatedly until the element of the original stream is consumed, and the third method accepts two parameters, both of which are ArrayList types, and the method body is to add the second ArrayList all to the first; The code is a bit cumbersome, Or use another overloaded method of collect:<r,a>R Collect (Collector Collector) notes that Collector is actually an aggregation of supplier, accumulator and combiner above. Then the above code becomes: Listlist= Stream.of (1, 2, 3, 4). Filter (P, p > 2). Collect (Collectors.tolist ()); Collect the results into map to define the following person object firstclassperson{ PublicString name;  Public intAge ; Person (String name,intAge ) {       This. Name =name;  This. Age =Age ; } @Override PublicString toString () {returnString.Format ("Person{name= '%s ', age=%d}", name, age); }} Suppose you have a stream object that you want to collect into a map so that you can find the corresponding age according to his name, for example: Map<string, integer= "" >result = People.collect (HashMap::New, (MAP,P)Map.put (p.name,p.age), map::p utall);/*Use collectors.tomap form*/Map<string, integer= "" >result = People.collect (Collectors.tomap (P.name, P-p.age, Exsit, NEWV)NEWV)); Where the third parameter of the Collectors.tomap method is the key-value repetition policy, if the third parameter is not passed in, a illeagestateexception is thrown when the same key is used. Or you want to break the person into a map store: List<map<string, object= "" >> Persontomap = People.collect (ArrayList::New, (list, p){Map<string, object= "" >map =NewHashmap<>(); Map.put ("Name", p.name); Map.put ("Age", P.age); List.add (map), list::addall); grouping and sharding grouping values with the same attributes is a common task, collectors provides a Groupingby method with the method signature:<t,k,a,d>collector<t,?, map<k,d>>Groupingby (Function classifier, Collector downstream) Classifier: A method that gets the primary key in the stream element. Downstream: A method that corresponds to the result of a grouping. If you want to group by age: Map<integer, list> peroplebyage = People.filter (P-p.age >). Collect (Collectors.groupingby (P-P.age, Collectors.tolist ())); If I want to group by age, the age corresponding to the key value list is stored as person's name, how to do it: Map<integer, list> peroplebyage = People.collect (Collectors.groupingby (P-p.age, collectors.mapping (person p) -p.name, Collectors.tolist ())); Mapping is the projection operation for each group, and the map method of stream is basically consistent. If you want to group by name, get each name the sum of the ages of the person (as if the need for some pit dad): Map<string, integer= "" >sumagebyname = People.collect (Collectors.groupingby (P-p.name, Collectors.reducing (0, (Person P)p.age, Integer::sum ));/*or use the Summingint method*/Sumagebyname= People.collect (Collectors.groupingby (P-, p.name, Collectors.summingint (person p)( p.age))); You can see that Java8 's grouping is quite powerful, but you can also do more complicated functions. In addition, there is a method similar to Groupingby in collectors: Partitioningby, the difference is Partitioningby is the key value of the Boolean type of Groupingby, In this case it is more efficient than the groupingby. Join and statistical functions The addition of a stringjoiner,collectors join function in JAVA8 is basically the same as it is. Used to stitch and collect strings in a stream, using simple: string names= People.map (p->p.name). Collect (Collectors.joining (",") collectors provides operations such as averaging averaging, total couting, minimum minby, maximum Maxby, sum suming, respectively. But if you want to aggregate the results of a stream into a sum, average, maximum, minimum, then collectors.summarizing (Int/long/double) is prepared for you, it can be a row to get all the previous results, its return value is (int/long/Double) Summarystatistics. Doublesummarystatistics DSS= People.collect (collectors.summarizingdouble (person p)p.age));DoubleAverage=dss.getaverage ();Doublemax=Dss.getmax ();Doublemin=dss.getmin ();Doublesum=dss.getsum ();DoubleCount=dss.getcount ();

Java8 aggregation operation collect, reduce method detailed

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.