-stream

Learning content

What is a Stream

In Java8, Collection has two new Stream methods,Stream () and parallelStream(). Stream is a Collection of elements that can be treated as a Stream. During the Stream process, a large number of operations can be performed on the Collection using Lambda expressions, such as: Filter, sort, aggregate, etc.

Sequential and parallel streams

Stream is order flow, by the main thread convection perform actions according to the order and parallelStream is parallel flows, internal convection in the form of multi-thread parallel execution, but the premise is the flow of data processing order requirements. For example, odd numbers in the filter set are filtered. The processing differences between the two are as follows:Parallel streams can speed things up if the amount of data in the stream is large enough. In addition to creating parallel streams directly, parallel() can be used to replace sequential streams with parallel streams

Why use Stream

Prior to Java8, it was common to resort and merge data using normal loops, for loops, or Iterator iterations, or by redefining the collections.sorts Comparator methods, both of which were not efficient for large numbers of systems. The aggregation of Stream is similar to that of database SQL: sorted, Filter, map, and so on. The application layer can efficiently realize the aggregation operation similar to database SQL. In terms of database operation, Stream can not only realize data operation through serial mode, but also process large quantities of data in parallel mode, improving the efficiency of data processing.

The Stream characteristics

  • Streams can be created from arrays or collections. There are two types of operations for streams:
    • Intermediate operations, which return a new stream at a time, can be multiple.
    • Terminal operation: Each stream can perform only one terminal operation. After the terminal operation, the stream cannot be used again. A terminal operation produces a new set or value.
  • A stream does not store data, but evaluates it according to specific rules, generally producing output.
  • Stream does not change the data source, and typically produces a new collection or a value.
  • Stream has a delayed execution property, where intermediate operations are executed only when terminal operations are called.

Common Entity Class

/** * @Description: todo * @Author: jianweil * @date: 2020/12/7 14:17 */ public class Person { private String name; // private int salary; // salary private int age; // Age private String sex; // Gender private String area; Public Person(String name, int salary, int age,String sex,String area) {this.name = name; this.salary = salary; this.age = age; this.sex = sex; this.area = area; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getSalary() { return salary; } public void setSalary(int salary) { this.salary = salary; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getArea() { return area; } public void setArea(String area) { this.area = area; }}Copy the code

Collect used

It is arguably the most varied and feature-rich part of the collection. Literally, a stream is collected, either as a value or as a new collection.

  • The collection (toList/toSet/toMap)

Since the stream does not store data, after the data in the stream is processed, the data in the stream needs to be regrouped into a new collection. ToList, toSet, and toMap are commonly used, as well as toCollection, toConcurrentMap, and other more complex usages.

  • Statistics (count/averaging)

    Collectors provides a series of static methods for collecting statistics:

    • Count: the count
    • Average value: averagingInt, averagingLong, averagingDouble
    • Maximum value: maxBy, minBy
    • Summing: summingInt, summingLong, summingDouble
    • SummarizingInt, summarizingLong, summarizingDouble
  • Group (partitioningBy/groupingBy)

    • Partitioning: Divide the stream into two maps based on criteria, such as whether employees are paid more than 8000.
    • Grouping: Divide the collection into multiple maps, such as employees grouped by gender. There are single-level and multi-level grouping.

  • Joint (joining)

    • Joining joins elements in a stream into a string using a specific concatenation (or, if not, directly).
  • Reduction (reducing)

    • The Reducing method provided by the Collectors class adds support for custom reduction compared to the Reduce method of stream itself.
  • Sorting (sorted)

    Sorted, middle operation. There are two sorts:

    • Sorted () : Sort naturally. Elements in a stream need to implement the Comparable interface
    • Sorted (Comparator com) : The Comparator sorter customizes sorts
  • Extraction/combination

    • Streams can also be merged, de-duplicated, restricted, and skipped

code

/**
 * @Description: 因为流不存储数据,那么在流中的数据完成处理后,需要将流中的数据重新归集到新的集合里。
*                toList、toSet和toMap比较常用,另外还有toCollection、toConcurrentMap等复杂一些的用法
 * @Author: jianweil
 * @date: 2020/12/8 9:31
 */
public class TestCollect {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 6, 3, 4, 6, 7, 9, 6, 20);
        List<Integer> listNew = list.stream().filter(x -> x % 2 == 0).collect(Collectors.toList());
        Set<Integer> set = list.stream().filter(x -> x % 2 == 0).collect(Collectors.toSet());

        List<Person> personList = new ArrayList<Person>();
        personList.add(new Person("Tom", 8900, 23, "male", "New York"));
        personList.add(new Person("Jack", 7000, 25, "male", "Washington"));
        personList.add(new Person("Lily", 7800, 25, "female", "Washington"));
        personList.add(new Person("Anni", 7800, 24, "female", "New York"));

        Map<?, Person> map = personList.stream().filter(p -> p.getSalary() > 8000)
                .collect(Collectors.toMap(Person::getName, p -> p));
        System.out.println("list:" + list);
        System.out.println("toList:" + listNew);
        System.out.println("toSet:" + set);
        System.out.println("toMap:" + map);


        // 求总数
        Long count = personList.stream().collect(Collectors.counting());
        // 求平均工资
        Double average = personList.stream().collect(Collectors.averagingDouble(Person::getSalary));
        // 求最高工资
        Optional<Integer> max = personList.stream().map(Person::getSalary).collect(Collectors.maxBy(Integer::compare));
        // 求工资之和
        Integer sum = personList.stream().collect(Collectors.summingInt(Person::getSalary));
        // 一次性统计所有信息
        DoubleSummaryStatistics collect = personList.stream().collect(Collectors.summarizingDouble(Person::getSalary));

        System.out.println("员工总数:" + count);
        System.out.println("员工平均工资:" + average);
        System.out.println("最高工资:" + max.get());
        System.out.println("员工工资总和:" + sum);
        System.out.println("员工工资所有统计:" + collect);



        /**
         * 分区:将stream按条件分为两个Map,比如员工按薪资是否高于8000分为两部分。
         *
         * 分组:将集合分为多个Map,比如员工按性别分组。有单级分组和多级分组。
         **/

        // 将员工按薪资是否高于8000分组
        Map<Boolean, List<Person>> part = personList.stream().collect(Collectors.partitioningBy(x -> x.getSalary() > 8000));
        // 将员工按性别分组
        Map<String, List<Person>> group = personList.stream().collect(Collectors.groupingBy(Person::getSex));
        // 将员工先按性别分组,再按地区分组
        Map<String, Map<String, List<Person>>> group2 = personList.stream().collect(Collectors.groupingBy(Person::getSex, Collectors.groupingBy(Person::getArea)));
        System.out.println("员工按薪资是否大于8000分组情况:" + part);
        System.out.println("员工按性别分组情况:" + group);
        System.out.println("员工按性别、地区:" + group2);

        /**
         * joining可以将stream中的元素用特定的连接符(没有的话,则直接连接)连接成一个字符串。
         */
        String names = personList.stream().map(p -> p.getName()).collect(Collectors.joining(","));
        System.out.println("所有员工的姓名:" + names);
        List<String> listJoining = Arrays.asList("A", "B", "C");
        String string = listJoining.stream().collect(Collectors.joining("-"));
        System.out.println("拼接后的字符串:" + string);

        /**
         * Collectors类提供的reducing方法,相比于stream本身的reduce方法,增加了对自定义归约的支持
         */
        // 每个员工减去起征点后的薪资之和(这个例子并不严谨,但一时没想到好的例子)
        personList.stream().map(person -> person.getSalary()).forEach(System.out::println);
        Integer sumCollect = personList.stream().collect(Collectors.reducing(0, Person::getSalary, (i, j) -> (i + j - 7000)));
        System.out.println("员工扣税薪资总和:" + sumCollect);

        // stream的reduce
        Optional<Integer> sum2 = personList.stream().map(Person::getSalary).reduce(Integer::sum);
        System.out.println("员工薪资总和:" + sum2.get());


        /**
         * sorted,中间操作。有两种排序:
         *
         * sorted():自然排序,流中元素需实现Comparable接口
         *
         * sorted(Comparator com):Comparator排序器自定义排序
         */

        // 按工资增序排序
        List<String> newList = personList.stream().sorted(Comparator.comparing(Person::getSalary)).map(Person::getName)
                .collect(Collectors.toList());
        // 按工资倒序排序
        List<String> newList2 = personList.stream().sorted(Comparator.comparing(Person::getSalary).reversed())
                .map(Person::getName).collect(Collectors.toList());
        // 先按工资再按年龄自然排序(从小到大)
        List<String> newList3 = personList.stream().sorted(Comparator.comparing(Person::getSalary).thenComparing(Comparator.comparing(p->p.getAge())))
                .map(Person::getName).collect(Collectors.toList());
        // 先按工资再按年龄自定义排序(从大到小)
        List<String> newList4 = personList.stream().sorted((p1, p2) -> {
            if (p1.getSalary() == p2.getSalary()) {
                return p2.getAge() - p1.getAge();
            } else {
                return p2.getSalary() - p1.getSalary();
            }
        }).map(Person::getName).collect(Collectors.toList());

        System.out.println("按工资自然排序:" + newList);
        System.out.println("按工资降序排序:" + newList2);
        System.out.println("先按工资再按年龄自然排序:" + newList3);
        System.out.println("先按工资再按年龄自定义降序排序:" + newList4);

        /**
         * 流也可以进行合并、去重、限制、跳过等操作。
         */
        String[] arr1 = { "a", "b", "c", "d" };
        String[] arr2 = { "d", "e", "f", "g" };

        Stream<String> stream1 = Stream.of(arr1);
        Stream<String> stream2 = Stream.of(arr2);
        // concat:合并两个流 distinct:去重
        List<String> newListDistinct = Stream.concat(stream1, stream2).distinct().collect(Collectors.toList());
        // limit:限制从流中获得前n个数据
        List<Integer> collectLimit = Stream.iterate(1, x -> x + 2).limit(10).collect(Collectors.toList());
        // skip:跳过前n个数据
        List<Integer> collectLimit2 = Stream.iterate(1, x -> x + 2).skip(1).limit(5).collect(Collectors.toList());

        System.out.println("流合并:" + newListDistinct);
        System.out.println("limit:" + collectLimit);
        System.out.println("skip:" + collectLimit2);


    }
}
Copy the code

The results

list:[1, 6, 3, 4, 6, 7, 9, 6, 20] toList:[6, 4, 6, 6, 20] toSet:[4, 20, 6] toMap: {Tom = com. LJW. Stream. The entity. 58 ceff1 Person @} workforce: 4 staff average wages: 7875.0 the highest salary: 8900 employees pay total: 31500 employee wages all statistics: DoubleSummaryStatistics {count = 4, sum = 31500.000000, min = 7000.000000, business = 7875.000000, Max =8900.000000} Employees are grouped according to whether their salary is greater than 8000: {false=[com.ljw.stream.entity.Person@548b7f67, com.ljw.stream.entity.Person@7ac7a4e4, Com. LJW. Stream. The entity. The Person @ 6 d78f375], true = [com. LJW. Stream. The entity. 58 ceff1] Person @} employees by gender group situation: {female=[com.ljw.stream.entity.Person@7ac7a4e4, com.ljw.stream.entity.Person@6d78f375], Male = [com. LJW. Stream. The entity. The Person @ 58 ceff1, com. LJW. Stream. The entity. The Person @ 548 b7f67]} employees by gender, region: {female={New York=[com.ljw.stream.entity.Person@6d78f375], Washington=[com.ljw.stream.entity.Person@7ac7a4e4]}, Male = {New York = [com. LJW. Stream. The entity. The Person @ 58 ceff1], Washington = [com. LJW. Stream. The entity. The Person @ 548 b7f67]}} all the employee's name: String concatenated by Tom,Jack,Lily,Anni: A-B-C 8900 7000 7800 7800 Total employee salary: 3500 Total employee salary: 31500 In descending order by salary: [Jack, Lily,Anni, Tom] [Tom, Lily, Anni, Jack] Sort by salary then by age: [A, B, C, D, E, F, g] LIMIT: [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]Copy the code

Traverse /find/match (foreach/find/match)

Schematic diagram

code

/** * * @Description: todo * @Author: jianweil * @date: 2020/12/7 14:05 * */ class TestForeachfindMatch { public static void main(String[] args) { List<Integer> list = Arrays.asList(7, 6, 9, 3, 8, 2, 1); List.stream ().filter(x -> x > 6).foreach (system.out ::println); // parallel list.stream().parallel().filter(x -> x > 6).foreach (system.out ::println); // Match first Optional<Integer> findFirst = list.stream().filter(x -> x > 6).findfirst (); // Match any Optional<Integer> findAny2 = list.stream().filter(x -> x > 6).findany (); // Match any (for parallel streams) Optional<Integer> findAny = list.parallelStream().filter(x -> x > 6).findany (); Boolean isMatch = list.stream().anymatch (x -> x >= 9); System.out.println(" match first value: "+ findfirst.get ()); System.out.println("findAny2 matches any value: "+ findany2.get ()); System.out.println(" match any value: "+ findany.get ()); System.out.println(" is there a value greater than or equal to 9: "+ isMatch); }}Copy the code

The results

FindAny2 Matches any value: 7 Matches any value: 8 Whether there is a value greater than or equal to 9: trueCopy the code

Filter

Schematic diagram

Filtering is an operation that verifies the elements in the stream according to certain rules and extracts the elements that meet the conditions into the new stream.

code

Public class TestFilter {public static void main(String[] args) {public static void main(String[] args) { List<Integer> List = array. asList(6, 7, 3, 8, 1, 2, 9); Stream<Integer> stream = list.stream(); stream.filter(x -> x > 7).forEach(System.out::println); // Select employees whose salary is above 8000 and form a new set. Collect List<Person> personList = new ArrayList<Person>(); personList.add(new Person("Tom", 8900, 23, "male", "New York")); personList.add(new Person("Jack", 7000, 25, "male", "Washington")); personList.add(new Person("Lily", 7800, 21, "female", "Washington")); personList.add(new Person("Anni", 8200, 24, "female", "New York")); personList.add(new Person("Owen", 9500, 25, "male", "New York")); personList.add(new Person("Alisa", 7900, 26, "female", "New York")); List<String> fiterList = personList.stream().filter(x -> x.getSalary() > 8000).filter(x -> x.getAge()>=24) .map(Person::getName).collect(Collectors.toList()); System.out.print(" name above 8000: "+ fiterList); }}Copy the code

The results

Name of employee above 8000: [Anni, Owen]Copy the code

Polymerization (Max/min/count)

Schematic diagram

Similar to mysql

code

Public class TestMax {public static void main(String[] args) {// Get the longest element in the String set. List<String> list = Arrays.asList("adnm", "admmt","aab", "aaa", "xbangd", "weoujgsd"); Optional<String> max = list.stream().max(Comparator.comparing(String::length)); Optional<String> min = list.stream().min(Comparator.comparing(String::length)); //weoujgsd system.out.println (" longest string: "+ max.get())); //aaa system.out. println(" shortest string: "+ min.get()); // Get the maximum value in the Integer set. List<Integer> list1 = Arrays.asList(7, 6, 9, 4, 11, 6); // Natural sort Optional<Integer> max1 = list1.stream().max(Integer::compareTo); Max2 = list1.stream(). Max (new Comparator<Integer>() {@override public int compare(Integer) o1, Integer o2) { return o1.compareTo(o2); }}); System.out.println(" natural sort Max: "+ max1.get()); System.out.println(" Custom sort Max: "+ max2.get()); // Get the highest paid employee. List<Person> personList = new ArrayList<Person>(); personList.add(new Person("Tom", 8900, 23, "male", "New York")); personList.add(new Person("Jack", 7000, 25, "male", "Washington")); personList.add(new Person("Lily", 7800, 21, "female", "Washington")); personList.add(new Person("Anni", 8200, 24, "female", "New York")); personList.add(new Person("Owen", 9500, 25, "male", "New York")); personList.add(new Person("Alisa", 7900, 26, "female", "New York")); Optional<Person> maxSalary = personList.stream().max(Comparator.comparingInt(Person::getSalary)); Println (" maxSalary: "+ maxSalary. Get ().getsalary ()); List<Integer> list4 = array. asList(7, 6, 4, 8, 2, 11, 9); long count = list4.stream().filter(x -> x >= 6).count(); System.out.println(" number of elements in list greater than =6: "+ count); }}Copy the code

The results

Longest string: weoujgsd Shortest string: aab Maximum value for natural sort: 11 Maximum value for custom sort: 11 Maximum value for employee salary: 9500 Number of elements greater than or equal to 6 in the list: 5Copy the code

Mapping (map/flatMap)

Schematic diagram

Mapping, you can map elements of one flow to another flow according to certain mapping rules. Divided into map and flatMap:

  • Map: Takes as an argument a function that is applied to each element and maps 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.

code

/** * @description: mapping, which can map elements of a stream to another stream according to certain mapping rules. Divided into map and flatMap: * map: takes as an argument a function that is applied to each element and maps it to a new element. * flatMap: Takes a function as an argument, replaces every value in the stream with another stream, and joins all streams into one stream. * @Author: jianweil * @date: 2020/12/7 14:54 */ public class TestMapAndFlatMap {public static void main(String[] args) {// All elements of the English String array are uppercase. Integer array +3 for each element. String[] strArr = { "abcd", "bcdd", "defde", "fTr" }; List<String> strList = Arrays.stream(strArr).map(String::toUpperCase).collect(Collectors.toList()); List<Integer> intList = Arrays.asList(1, 3, 5, 7, 9, 11); List<Integer> intListNew = intList.stream().map(x -> x + 3).collect(Collectors.toList()); System.out.println(" each element uppercase: "+ strList); System.out.println(" each element +3: "+ intListNew); // Increase all employees' salaries by 1000. List<Person> personList = new ArrayList<Person>(); personList.add(new Person("Tom", 8900, 23, "male", "New York")); personList.add(new Person("Jack", 7000, 25, "male", "Washington")); personList.add(new Person("Lily", 7800, 21, "female", "Washington")); personList.add(new Person("Anni", 8200, 24, "female", "New York")); personList.add(new Person("Owen", 9500, 25, "male", "New York")); personList.add(new Person("Alisa", 7900, 26, "female", "New York")); List<Person> personListNew = personlist.stream ().map(Person -> {Person personNew = new Person(person.getName(), 0, 0, null, null); personNew.setSalary(person.getSalary() + 10000); return personNew; }).collect(Collectors.toList()); Println (" + personList.get(0).getName() + "-->" + PersonList.get (0).getsalary ()); Println (" + PersonListNew.get (0).getName() + "-->" + PersonListNew.get (0).getsalary ()); List<Person> personListNew2 = personlist.stream ().map(Person -> { person.setSalary(person.getSalary() + 10000); return person; }).collect(Collectors.toList()); Println (" + PersonList.get (0).getName() + "-->" + PersonListNew.get (0).getsalary ()); Println (" + PersonListNew2.get (0).getName() + "-->" + PersonListNew.get (0).getsalary ()); // Combine two character arrays into a new character array. List<String> list = Arrays.asList("m-k-l-a", "1-3-5-7"); List<String> listNew = list.stream().flatmap (s -> {// Convert each element to a stream String[] split = s.split("-"); Stream<String> s2 = Arrays.stream(split); return s2; }).collect(Collectors.toList()); System.out.println(" set before processing: "+ list); System.out.println(" processed collection: "+ listNew); }}Copy the code

The results

[ABCD, BCDD, DEFDE, FTR] Each element +3: [4, 6, 8, 10, 12, 14] Before one change: Tom-->8900 After one change: Tom-->18900 After two changes: Tom-->18900 After two changes: Tom - > 18900 collection before processing: [m - k - l - a, the 1-3-5-7) after processing collection: [m, k, l, a, 1, 3, 5, 7)Copy the code

Reduction (reduce)

Schematic diagram

Reduction, also known as reduction, as the name implies, is to reduce a stream to a value, can achieve the sum of sets, products and maximization operations.

Reduce () differs from overloaded functions

  • A parameter

Optional reduce(BinaryOperator accumulator);

Suppose the element a[0]/a[1]/a[2] in Stream… A [n-1], which expresses the computational meaning, is expressed in Java code as follows: that is, a[0] is combined with a[1], and the result is combined with a[2], until finally it is combined with a[n-1].

Java logic code

/* * T result = a[0]; * for (int i = 1; i < n; i++) { * result = accumulator.apply(result, a[i]); * } * return result; * /Copy the code

code

Supplier<Stream<Integer>> s = ()-> Stream.of(1, 2, 3, 4, 5, 6); * Integer sum = s.pie ((a, b) -> a + b).get(); */ Integer sumBinaryOperator = s.get().reduce(new BinaryOperator<Integer>() { @Override public Integer apply(Integer integer, Integer integer2) { return integer + integer2; } }).get(); Integer lambdaSum = s.get().reduce((a, b) -> a + b).get(); System.out.println(" sum: "+sumBinaryOperator); System.out.println("1 argument lambdaSum: "+lambdaSum); * Integer Max = s. duce((a, b) -> a >= b? a : b).get(); */ Integer maxBinaryOperator = s.get().reduce(new BinaryOperator<Integer>() { @Override public Integer apply(Integer integer, Integer integer2) { return integer >= integer2 ? integer : integer2; } }).get(); Integer lambdaMax = s.get().reduce((a, b) -> a >= b ? a : b).get(); System.out.println("1 argument Max: "+maxBinaryOperator); System.out.println("1 argument lambdaSum: "+lambdaMax);Copy the code

The results of

1 parameter sum: 21 1 parameter lambdaSum: 21 1 parameter Max: 6 1 parameter lambdaSum: 6Copy the code
  • Two parameters

T reduce(T identity, BinaryOperator accumulator);

Sequential streams are different from parallel streams, where each stream has an initial value of identity

Java logic code

** T result = identity; * for (int i = 0; i < n; i++) { * result = accumulator.apply(result, a[i]); * } * return result; * /Copy the code

code

Supplier<Stream<String>> str = ()->Stream.of("test", "t1", "t2", "teeeee", "aaaa", "taaa"); /** * The following result will be: [value] testt1t2teeeEEaaaataaa * Lambda syntax can also be used:  * System.out.println(s.reduce("[value]", (s1, s2) -> s1.concat(s2))); */ String s1 = str.get().reduce("[value]", new BinaryOperator<String>() { @Override public String apply(String s11, String s22) { return s11.concat(s22); } }).toString(); System.out.println(s1); String s2 = str.get().reduce("[value]", (s11, s22) -> s11.concat(s22)).toString(); System.out.println(s2); A List < Integer > intList = Arrays. AsList (1, 2, 3); // The sequential stream result is 106. Integer result2=intList.stream().reduce(100, Integer::sum); System.out.println(result2); 306 Integer result3= intList.parallelstream ().reduce(100, Integer::sum); System.out.println(result3);Copy the code

The results of

[value]testt1t2teeeeeaaaataaa
[value]testt1t2teeeeeaaaataaa
106
306
Copy the code

Sequential flow results 106; Parallel flow result 306? Why 306?

Because in parallel computing, each thread starts with a sum of 100, the last three threads add up to 306. Parallelism is not the same as parallelism. It is not the same as parallelism.

Identity must be an identity of the Accumulator function. Accumulator. Apply (identity, t) ==t = 1.

The identity of the sum method can only be 0. If we use 0 as identity, stream and parallelStream compute the same. This is what Identity is really about. *

  • Three parameters

    U reduce(U identity,BiFunction<U, ? super T, U> accumulator,BinaryOperator combiner);

    Different from the previous method, there is a combiner, which is used to merge the results of multi-thread calculation. In the same way, Apply (u, accumulator. Apply (identity, t)) == accumulator. Apply (u, accumulator) T) The accumulator is of type BiFunction and is of type BinaryOperator.

    public interface BinaryOperator extends BiFunction<T,T,T>

    BinaryOperator is a subinterface of BiFunction. BiFunction defines the Apply method to implement. In fact, the implementation of the underlying Reduce method only uses the Apply method and does not use other methods in the interface, so I guess the difference here is just for simple distinction.

    The third parameter combiner is mainly used in parallel computing scenarios. The third argument is actually invalid if Stream is non-parallel.

Equivalent to Java logic code

** U result = identity; ** U result = identity; * for (T element : this stream) * result = accumulator.apply(result, element) * return result; * /Copy the code

code

System.out.println(Stream.of(1, 2, 3).parallel().reduce(4, new BiFunction<Integer, Integer, Integer>() { @Override public Integer apply(Integer integer, Integer integer2) { return integer + integer2; } } , new BinaryOperator<Integer>() { @Override public Integer apply(Integer integer, Integer integer2) { return integer * integer2; }})); // Reduce can be written in the same way as: Println (stream.of (1, 2, 3).map(n -> n + 4).reduce((s111, s222) -> s111 * s222)); /** * Emulated Filter finds all elements containing the letter a, and prints aa ab AD * lambda syntax:  * s1.parallel().reduce(new ArrayList<String>(), (r, t) -> {if (predicate.test(t)) r.add(t); return r; }, (r1, r2) -> {System.out.println(r1==r2); return r2; }).stream().forEach(System.out::println); */ System.out.println("s33"); Stream<String> s33 = Stream.of("aa", "ab", "c", "ad"); Predicate<String> predicate = t -> t.contains("a"); s33.parallel().reduce(new ArrayList<String>(), new BiFunction<ArrayList<String>, String, ArrayList<String>>() { @Override public ArrayList<String> apply(ArrayList<String> strings, String s) { if (predicate.test(s)) { strings.add(s); } return strings; } }, new BinaryOperator<ArrayList<String>>() { @Override public ArrayList<String> apply(ArrayList<String> strings, ArrayList<String> strings2) { System.out.println(strings == strings2); return strings; } }).stream().forEach(System.out::println); System.out.println("s333"); Stream<String> s333 = Stream.of("aa", "ab", "c", "ad"); R1.addall (r2); Aa ab AD s333.parallel().reduce(new ArrayList<String>(), (r, t) -> {if (predicate. Test (t)) r.ade (t); return r; }, (r1, r2) -> {r1.addAll(r2); return r1; }).stream().forEach(System.out::println);Copy the code

The results of

210
Optional[210]
s33
true
true
true
ad
ab
aa
s333
ad
aa
ad
aa
ab
ad
aa
ad
aa
ab
ad
aa
ad
aa
ab
ad
aa
ad
aa
ab
Copy the code

other

Public class TestReduce {public static void main(String[] args) { List<Integer> List = Arrays. AsList (1, 3, 2, 8, 11, 4,12); / / the List < Integer > List = Arrays. The asList (0, 0); 1 Optional<Integer> sumXY = list.stream().reduce((x, y) -> x + y); 2 Optional<Integer> sumInteger = list.stream().reduce(Integer::sum); 3 Integer sum3 = list.stream().reduce(0, Integer::sum); // Find the product Optional<Integer> product = list.stream().reduce((x, y) -> x * y); 1 Optional<Integer> maxXY = list.stream().reduce((x, y) -> x > y? x : y); 2 Integer maxInteger = list.stream().reduce(1, Integer:: Max); Println (" sumxy.get () + "," suminteger.get () + "," sum3); System.out.println(" product: "+ product.get()); System.out.println("list for Max: "+ maxxy.get () + "," + maxInteger); // Get the maximum value in the Integer set. // Natural sort Optional<Integer> maxIntegerMax = list.stream().max(Integer::compareTo); System.out.println(" natural sort Max: "+ maxintegermax.get ()); List<Person> personList = new ArrayList<Person>(); personList.add(new Person("Tom", 8900, 23, "male", "New York")); personList.add(new Person("Jack", 7000, 25, "male", "Washington")); personList.add(new Person("Lily", 7800, 21, "female", "Washington")); personList.add(new Person("Anni", 8200, 24, "female", "New York")); personList.add(new Person("Owen", 9500, 25, "male", "New York")); personList.add(new Person("Alisa", 7900, 26, "female", "New York")); 1: Optional<Integer> sumSalary = personList.stream().map(Person::getSalary).reduce(Integer::sum); // Get the sum of the salary.  Integer sumSalary2 = personList.stream().reduce(0, (sum, p) -> sum += p.getSalary(),(sum1, sum2) -> sum1 + sum2); SumSalary3 = personlist.stream ().reduce(0, (sum, p) -> sum += p.getsalary (), Integer::sum); Integer sumSalary4 = personlist.stream ().collect(Collectors. SummingInt (Person::getSalary)); Integer maxSalary = personlist.stream ().reduce(0, (Max, p) -> Max > p.getsalary ()? max : p.getSalary(), Integer::max); Integer maxSalary2 = personlist.stream ().reduce(0, (Max, p) -> Max > p.getsalary ()? max : p.getSalary(), (max1, max2) -> max1 > max2 ? max1 : max2); // Get the highest salary  Optional<Integer> maxSalary3 = personList.stream().map(Person::getSalary).collect(Collectors.maxBy(Integer::compare)); Println (" + salary2 +"," + sumSalary3+" "+sumSalary4); Println (" maxSalary: "+ maxSalary2+ ","+maxSalary3. Get ()); }}Copy the code

The results

Total salary: 49300,49300,49300,49300 maximum salary: 9500,9500,9500Copy the code

This article has share to github:https://github.com/liangjianweiLJW/java8/tree/master/src/com/ljw/stream example source code

Refer to the article: https://blog.csdn.net/mu_wind/article/details/109516995 article derived from the network, if there are any infringement, please let us know, will be deleted.