20 instances play with Java 8 Stream

First post a few cases. Students with high level can challenge:

  1. Select employees with salary greater than 8000 from the employee set and place them in a new set.
  2. Count the sum of the maximum salary, average salary and salary of employees.
  3. Employees are ranked from high to low in salary, and the younger ones are the first.
  4. Classify employees by gender, classify employees by gender and region, and divide employees into two parts according to whether their salary is higher than 8000.

Using traditional iterative processing is not very difficult, but the code is redundant, which is superior to Stream.

1 Stream overview

Java 8 is a very successful version. The new Stream in this version and Lambda in the contract version provide great convenience for us to operate the Collection.

So what is Stream?

Stream regards the set of elements to be processed as a stream. In the process of streaming, the Stream API is used to operate the elements in the stream, such as filtering, sorting, aggregation, etc.

Stream s can be created from arrays or collections. There are two kinds of operations for convection:

  1. Intermediate operations return a new stream each time, and there can be multiple.
  2. Terminal operation. Each stream can only perform terminal operation once. After the terminal operation, the stream cannot be used again. A terminal operation generates a new set or value.

In addition, Stream has several features:

  1. stream does not store data, but calculates the data according to specific rules, and generally outputs the results.
  2. stream does not change the data source and usually produces a new set or a value.
  3. stream has the characteristic of delayed execution, and the intermediate operation will be executed only when the terminal operation is called.

2. Creation of stream

A Stream can be created from a collection array.

1. Through Java util. Collection. The stream () method creates a stream from a collection

List<String> list = Arrays.asList("a", "b", "c");
// Create a sequential flow
Stream<String> stream = list.stream();
// Create a parallel stream
Stream<String> parallelStream = list.parallelStream();

2. Using Java util. Arrays. The stream (t [] array) method creates a stream with an array

int[] array={1,3,5,6,8};
IntStream stream = Arrays.stream(array);

3. Static methods using Stream: of(), iterate(), generate()

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);

Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 3).limit(4);
stream2.forEach(System.out::println); // 0 2 4 6 8 10

Stream<Double> stream3 = Stream.generate(Math::random).limit(3);
stream3.forEach(System.out::println);

Output results:

0 3 6 9 0.6796156909271994 0.1914314208854283 0.8116932592396652

Simple distinction between stream and parallel stream: stream is a sequential stream, and the main thread performs operations in sequence, while parallel stream is a parallel stream, which internally performs operations in the form of multi-threaded parallel execution, but the premise is that there is no sequence requirement for data processing in the stream. For example, odd numbers in the filter set are handled differently:

If the amount of data in the stream is large enough, the parallel stream can speed up. There are 10 ways to create a Stream in Java 8, Take a look at this recommendation.

In addition to directly creating parallel streams, you can also convert sequential streams into parallel streams through parallel():

Optional<Integer> findFirst = list.stream().parallel().filter(x->x>6).findFirst();

3. Use of stream

Before using stream, first understand a concept: Optional.

The Optional class is a null able container object. If the value exists, the isPresent() method will return true, and calling the get() method will return the object. For more details, see the rookie tutorial Java 8 Optional class

Next, a lot of code comes to you! I will use 20 cases to make the use of Stream clear. As long as I knock the code again, I can master it well.

Employee class used in the case

This is the Employee class used in the following cases:

List<Person> personList = new ArrayList<Person>();
personList.add(new Person("Tom", 8900, "male", "New York"));
personList.add(new Person("Jack", 7000, "male", "Washington"));
personList.add(new Person("Lily", 7800, "female", "Washington"));
personList.add(new Person("Anni", 8200, "female", "New York"));
personList.add(new Person("Owen", 9500, "male", "New York"));
personList.add(new Person("Alisa", 7900, "female", "New York"));

class Person {
 private String name;  // full name
 private int salary; // salary
 private int age; // Age
 private String sex; //Gender
 private String area;  // region

 // Construction method
 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;
 }
 // get and set are omitted. Please add them yourself

}

3.1 foreach/find/match

Stream also supports traversal and matching elements of similar collections, but the elements in stream exist as Optional types. The traversal and matching of stream is very simple. In addition, all the Java 8 series tutorials and examples have been sorted out. Wechat searches the Java technology stack and sends it in the background: Java, which can be read online.

// import has been omitted, please add it yourself, and the following code is also

public class StreamTest {
 public static void main(String[] args) {
        List<Integer> list = Arrays.asList(7, 6, 9, 3, 8, 2, 1);

        // Traverse the elements whose output meets the criteria
        list.stream().filter(x -> x > 6).forEach(System.out::println);
        // Match first
        Optional<Integer> findFirst = list.stream().filter(x -> x > 6).findFirst();
        // Match any (for parallel streams)
        Optional<Integer> findAny = list.parallelStream().filter(x -> x > 6).findAny();
        // Whether to include elements that meet specific conditions
        boolean anyMatch = list.stream().anyMatch(x -> x < 6);
        System.out.println("Match first value:" + findFirst.get());
        System.out.println("Match any value:" + findAny.get());
        System.out.println("Is there a value greater than 6:" + anyMatch);
    }
}

3.2 filter

Filtering is the operation of verifying the elements in the flow according to certain rules and extracting the qualified elements into the new flow.

Case 1: filter out the elements greater than 7 in the Integer set and print them

public class StreamTest {
 public static void main(String[] args) {
  List<Integer> list = Arrays.asList(6, 7, 3, 8, 1, 2, 9);
  Stream<Integer> stream = list.stream();
  stream.filter(x -> x > 7).forEach(System.out::println);
 }
}

Expected results:

8 9

Case 2: select employees with wages higher than 8000 and form a new collection. Forming a new collection depends on collection, which will be described in detail later.

public class StreamTest {
 public static void main(String[] args) {
  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).map(Person::getName)
    .collect(Collectors.toList());
  System.out.print("Name of employees above 8000:" + fiterList);
 }
}

Operation results:

Name of employees above 8000: [Tom, Anni, Owen]

3.3 polymerization (max/min/count)

You must be familiar with the words max, min and count. Yes, we often use them for data statistics in mysql. These concepts and usages are also introduced into Java stream, which greatly facilitates our data statistics of sets and arrays.

Latest Java} core technology tutorials and sample source code: https://github.com/javastacks/javastack

Case 1: get the longest element in the String set.

public class StreamTest {
 public static void main(String[] args) {
  List<String> list = Arrays.asList("adnm", "admmt", "pot", "xbangd", "weoujgsd");

  Optional<String> max = list.stream().max(Comparator.comparing(String::length));
  System.out.println("Longest string:" + max.get());
 }
}

Output results:

Longest string: weoujgsd

Case 2: get the maximum value in the Integer set.

public class StreamTest {
 public static void main(String[] args) {
  List<Integer> list = Arrays.asList(7, 6, 9, 4, 11, 6);

  // Natural sorting
  Optional<Integer> max = list.stream().max(Integer::compareTo);
  // Custom sorting
  Optional<Integer> max2 = list.stream().max(new Comparator<Integer>() {
   @Override
   public int compare(Integer o1, Integer o2) {
    return o1.compareTo(o2);
   }
  });
  System.out.println("Maximum natural sort:" + max.get());
  System.out.println("Maximum value of custom sort:" + max2.get());
 }
}

Output results:

Maximum value of natural sort: 11 maximum value of custom sort: 11

Case 3: the person who gets the highest salary.

public class StreamTest {
 public static void main(String[] args) {
  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> max = personList.stream().max(Comparator.comparingInt(Person::getSalary));
  System.out.println("Maximum employee salary:" + max.get().getSalary());
 }
}

Output results:

Maximum employee salary: 9500

Case 4: calculate the number of elements greater than 6 in the Integer set.

import java.util.Arrays;
import java.util.List;

public class StreamTest {
 public static void main(String[] args) {
  List<Integer> list = Arrays.asList(7, 6, 4, 8, 2, 11, 9);

  long count = list.stream().filter(x -> x > 6).count();
  System.out.println("list Number of elements greater than 6 in:" + count);
 }
}

Output results:

Number of elements greater than 6 in the list: 4

3.4 mapping (map/flatMap)

Mapping, the elements of one flow can be mapped to another flow according to certain mapping rules. It is divided into map and flatMap:

  • map: takes a function as an argument, which is applied to each element and mapped to a new element.

  • flatMap: take a function as a parameter, replace each value in the stream with another stream, and then connect all streams into one stream.

Case 1: all elements of the English string array are changed to uppercase. Integer array + 3 per element.

public class StreamTest {
 public static void main(String[] args) {
  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("Capitalize each element:" + strList);
  System.out.println("Each element+3: " + intListNew);
 }
}

Output results:

Capitalize each element: [ABCD, BCDD, DEFDE, FTR] each element + 3: [4, 6, 8, 10, 12, 14]

Case 2: increase the salary of all employees by 1000. 

public class StreamTest {
 public static void main(String[] args) {
  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"));

  // Do not change the way the original employees are assembled
  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());
  System.out.println("Before one change:" + personList.get(0).getName() + "-->" + personList.get(0).getSalary());
  System.out.println("After one change:" + personListNew.get(0).getName() + "-->" + personListNew.get(0).getSalary());

  // Change the way employees gather
  List<Person> personListNew2 = personList.stream().map(person -> {
   person.setSalary(person.getSalary() + 10000);
   return person;
  }).collect(Collectors.toList());
  System.out.println("Before the second change:" + personList.get(0).getName() + "-->" + personListNew.get(0).getSalary());
  System.out.println("After the second change:" + personListNew2.get(0).getName() + "-->" + personListNew.get(0).getSalary());
 }
}

Output results:

Before the first change: Tom – > 8900 after the first change: Tom – > 18900 before the second change: Tom – > 18900 after the second change: Tom – > 18900

Case 3: combine two character arrays into a new character array.

public class StreamTest {
 public static void main(String[] args) {
  List<String> list = Arrays.asList("m,k,l,a", "1,3,5,7");
  List<String> listNew = list.stream().flatMap(s -> {
   // Convert each element into a stream
   String[] split = s.split(",");
   Stream<String> s2 = Arrays.stream(split);
   return s2;
  }).collect(Collectors.toList());

  System.out.println("Collection before processing:" + list);
  System.out.println("Processed collection:" + listNew);
 }
}

Output results:

Set before processing: [m-k-l-a, 1-3-5] set after processing: [m, k, l, a, 1, 3, 5]

3.5 reduce

Recommended reading: The latest Java core technology tutorials are here!

Reduction, also known as reduction, as the name suggests, is to reduce a stream to a value, which can realize the operations of summation, product and maximum of a set.

Case 1: find the sum, product and maximum of the elements of the Integer set.

public class StreamTest {
 public static void main(String[] args) {
  List<Integer> list = Arrays.asList(1, 3, 2, 8, 11, 4);
  // Summation method 1
  Optional<Integer> sum = list.stream().reduce((x, y) -> x + y);
  // Summation method 2
  Optional<Integer> sum2 = list.stream().reduce(Integer::sum);
  // Summation method 3
  Integer sum3 = list.stream().reduce(0, Integer::sum);

  // Product
  Optional<Integer> product = list.stream().reduce((x, y) -> x * y);

  // Maximum method 1
  Optional<Integer> max = list.stream().reduce((x, y) -> x > y ? x : y);
  // Find the maximum 2
  Integer max2 = list.stream().reduce(1, Integer::max);

  System.out.println("list Summation:" + sum.get() + "," + sum2.get() + "," + sum3);
  System.out.println("list Quadrature:" + product.get());
  System.out.println("list Summation:" + max.get() + "," + max2);
 }
}

Output results:

List summation: 29,29,29 list quadrature: 2112 list summation: 11,11

Case 2: seek the sum of the wages of all employees and the maximum wage.

public class StreamTest {
 public static void main(String[] args) {
  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"));

  //Sum of wages method 1:
  Optional<Integer> sumSalary = personList.stream().map(Person::getSalary).reduce(Integer::sum);
  //Sum of wages method 2:
  Integer sumSalary2 = personList.stream().reduce(0, (sum, p) -> sum += p.getSalary(),
    (sum1, sum2) -> sum1 + sum2);
  //Sum of wages method 3:
  Integer sumSalary3 = personList.stream().reduce(0, (sum, p) -> sum += p.getSalary(), Integer::sum);

  //Maximum wage method 1:
  Integer maxSalary = personList.stream().reduce(0, (max, p) -> max > p.getSalary() ? max : p.getSalary(),
    Integer::max);
  //Maximum wage method 2:
  Integer maxSalary2 = personList.stream().reduce(0, (max, p) -> max > p.getSalary() ? max : p.getSalary(),
    (max1, max2) -> max1 > max2 ? max1 : max2);

  System.out.println("Sum of wages:" + sumSalary.get() + "," + sumSalary2 + "," + sumSalary3);
  System.out.println("Maximum wage:" + maxSalary + "," + maxSalary2);
 }
}

Output results:

Sum of wages: 493004930049300 maximum wage: 95009500

3.6 collect

Collection, collection, can be said to be the most diverse and functional part. Literally, it means collecting a stream, which can eventually be collected into a value or a new collection.

collect mainly relies on Java util. stream. Static methods built into the collectors class.

3.6. 1 collection (toList/toSet/toMap)

Because the stream does not store data, after the data in the stream is processed, the data in the stream needs to be re collected into a new set. toList, toSet and toMap are commonly used. In addition, there are more complex usages such as toCollection and tocurrentmap.

The following example demonstrates toList, toSet and toMap:

public class StreamTest {
 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, 21, "female", "Washington"));
  personList.add(new Person("Anni", 8200, 24, "female", "New York"));

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

Operation results:

toList: [6, 4, 6, 6, 20] toSet: [4, 20, 6] toMap: {Tom=mutest.Person@5fd0d5ae, Anni=mutest.Person@2d98a335}

3.6. 2 Statistics (count/averaging)

Collectors provide a series of static methods for data statistics:

  • Count: count

  • Average value: averagingInt, averagingLong, averagingDouble

  • Max value: maxBy, minBy

  • Summation: summerint, summerlong, summerdouble

  • Statistics of all the above: summarizingInt, summarizingLong, summarizingDouble

Case: count the number of employees, average salary, total salary and maximum salary.

public class StreamTest {
 public static void main(String[] args) {
  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"));

  //Total
  Long count = personList.stream().collect(Collectors.counting());
  //Average wage
  Double average = personList.stream().collect(Collectors.averagingDouble(Person::getSalary));
  //Seek maximum wage
  Optional<Integer> max = personList.stream().map(Person::getSalary).collect(Collectors.maxBy(Integer::compare));
  //Sum of wages
  Integer sum = personList.stream().collect(Collectors.summingInt(Person::getSalary));
  //One time statistics of all information
  DoubleSummaryStatistics collect = personList.stream().collect(Collectors.summarizingDouble(Person::getSalary));

  System.out.println("Total number of employees:" + count);
  System.out.println("Average salary of employees:" + average);
  System.out.println("Total employee salary:" + sum);
  System.out.println("Employee salary statistics:" + collect);
 }
}

Operation results:

Total number of employees: 3 average wages of employees: 7900.0 total wages of employees: 23700 wages of employees all statistics: DoubleSummaryStatistics{count=3, sum=23700.000000,min=7000.000000, average=7900.000000, max=8900.000000}

3.6. 3 grouping (partitioningBy/groupingBy)

  • Partition: divide the stream into two maps according to conditions. For example, employees are divided into two parts according to whether their salary is higher than 8000.

  • Grouping: divide the set into multiple maps, such as grouping employees by gender. There are single level grouping and multi-level grouping.

  • Case: divide employees into two parts according to whether their salary is higher than 8000; Group employees by gender and region

public class StreamTest {
 public static void main(String[] args) {
  List<Person> personList = new ArrayList<Person>();
  personList.add(new Person("Tom", 8900, "male", "New York"));
  personList.add(new Person("Jack", 7000, "male", "Washington"));
  personList.add(new Person("Lily", 7800, "female", "Washington"));
  personList.add(new Person("Anni", 8200, "female", "New York"));
  personList.add(new Person("Owen", 9500, "male", "New York"));
  personList.add(new Person("Alisa", 7900, "female", "New York"));

  //Group employees by salary above 8000
        Map<Boolean, List<Person>> part = personList.stream().collect(Collectors.partitioningBy(x -> x.getSalary() > 8000));
        //Group employees by gender
        Map<String, List<Person>> group = personList.stream().collect(Collectors.groupingBy(Person::getSex));
        //Employees are grouped first by gender and then by region
        Map<String, Map<String, List<Person>>> group2 = personList.stream().collect(Collectors.groupingBy(Person::getSex, Collectors.groupingBy(Person::getArea)));
        System.out.println("Grouping of employees by salary greater than 8000:" + part);
        System.out.println("Employees are grouped by gender:" + group);
        System.out.println("Employees by gender and region:" + group2);
 }
}

Output results:

Grouping of employees by salary greater than 8000:{false=[mutest.Person@2d98a335, mutest.Person@16b98e56, mutest.Person@7ef20235], true=[mutest.Person@27d6c5e0, mutest.Person@4f3f5b24, mutest.Person@15aeb7ab]}  

Employees are grouped by gender:{female=[mutest.Person@16b98e56, mutest.Person@4f3f5b24, mutest.Person@7ef20235], male=[mutest.Person@27d6c5e0, mutest.Person@2d98a335, mutest.Person@15aeb7ab]}  

Employees by gender and region:{female={New York=[mutest.Person@4f3f5b24, mutest.Person@7ef20235], Washington=[mutest.Person@16b98e56]}, male={New York=[mutest.Person@27d6c5e0, mutest.Person@15aeb7ab], Washington=[mutest.Person@2d98a335]}}  

3.6. 4 joining

joining can connect the elements in the stream into a string with a specific connector (or directly if not).

joining can connect the elements in the stream into a string with a specific connector (or directly if not).

public class StreamTest {
 public static void main(String[] args) {
  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"));

  String names = personList.stream().map(p -> p.getName()).collect(Collectors.joining(","));
  System.out.println("Names of all employees:" + names);
  List<String> list = Arrays.asList("A", "B", "C");
  String string = list.stream().collect(Collectors.joining("-"));
  System.out.println("Spliced string:" + string);
 }
}

Operation results:

Names of all employees: Tom,Jack,Lily, spliced string: A-B-C

3.6. 5 reduction

Compared with the reduce method of stream itself, the reducing method provided by the Collectors class adds support for custom reduction.

public class StreamTest {
 public static void main(String[] args) {
  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"));

  //The sum of the salary of each employee after deducting the threshold (this example is not rigorous, but I didn't expect a good example at the moment)
  Integer sum = personList.stream().collect(Collectors.reducing(0, Person::getSalary, (i, j) -> (i + j - 5000)));
  System.out.println("Total tax deduction salary of employees:" + sum);

  //reduce of stream
  Optional<Integer> sum2 = personList.stream().map(Person::getSalary).reduce(Integer::sum);
  System.out.println("Total employee salary:" + sum2.get());
 }
}

Operation results:

Total employee tax deduction salary: 8700 total employee salary: 23700

3.7 sorted

sorted, intermediate operation. There are two sorts:

  • sorted(): sort naturally. Elements in the stream need to implement the Comparable interface

  • sorted(Comparator com): Comparator sorter custom sorting

Case: sort employees by salary from high to low (if the salary is the same, then by age)

public class StreamTest {
 public static void main(String[] args) {
  List<Person> personList = new ArrayList<Person>();

  personList.add(new Person("Sherry", 9000, 24, "female", "New York"));
  personList.add(new Person("Tom", 8900, 22, "male", "Washington"));
  personList.add(new Person("Jack", 9000, 25, "male", "Washington"));
  personList.add(new Person("Lily", 8800, 26, "male", "New York"));
  personList.add(new Person("Alisa", 9000, 26, "female", "New York"));

  // Sort by salary ascending (natural sort)
  List<String> newList = personList.stream().sorted(Comparator.comparing(Person::getSalary)).map(Person::getName)
    .collect(Collectors.toList());
  // Sort by salary in reverse order
  List<String> newList2 = personList.stream().sorted(Comparator.comparing(Person::getSalary).reversed())
    .map(Person::getName).collect(Collectors.toList());
  // Sort by salary and then by age
  List<String> newList3 = personList.stream()
    .sorted(Comparator.comparing(Person::getSalary).thenComparing(Person::getAge)).map(Person::getName)
    .collect(Collectors.toList());
  // Sort by salary first and then by age (descending order)
  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("Sort by salary in ascending order:" + newList);
  System.out.println("Sort by salary in descending order:" + newList2);
  System.out.println("Sort by salary first and then by age in ascending order:" + newList3);
  System.out.println("Sort by salary first and then by age in descending order:" + newList4);
 }
}

 

Operation results:

Sort by salary: [Lily, Tom, Sherry, Jack, Alisa] sort by salary in descending order: [Sherry, Jack, Alisa,Tom, Lily] sort by salary first and then by age: [Sherry, Jack, Alisa,Tom, Lily] sort by salary first and then custom descending order by age: [Alisa, Jack, Sherry, Tom, Lily]

3.8 extraction / combination

Streams can also be merged, de duplicated, restricted, and skipped.

public class StreamTest {
 public static void main(String[] args) {
  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: merge two streams distinct: de duplication
  List<String> newList = Stream.concat(stream1, stream2).distinct().collect(Collectors.toList());
  //Limit: limit the first n data obtained from the stream
  List<Integer> collect = Stream.iterate(1, x -> x + 2).limit(10).collect(Collectors.toList());
  // Skip: skip the first n data
  List<Integer> collect2 = Stream.iterate(1, x -> x + 2).skip(1).limit(5).collect(Collectors.toList());

  System.out.println("Stream merge:" + newList);
  System.out.println("limit: " + collect);
  System.out.println("skip: " + collect2);
 }
}

Operation results:

Stream merging: [a, b, c, d, e, f, g] limit: [1, 3, 5, 7, 9, 11, 13, 15, 17, 19] skip: [3, 5, 7, 9, 11]

3.9 grouping

public class Java8Example1 {

    public static void main(String[] args) {

        List<String> items = Arrays.asList(
                "apple", "apple",
                "orange", "orange", "orange",
                "blueberry",
                "peach", "peach", "peach", "peach"
        );

        // Grouping, counting
        Map<String, Long> result = items.stream()
                .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

        System.out.println(result);

        Map<String, Long> finalMap = new LinkedHashMap<>();
        // Reverse sort
        result.entrySet().stream()
                .sorted(Map.Entry.<String, Long>comparingByValue().reversed())
                .forEachOrdered(e -> finalMap.put(e.getKey(), e.getValue()));

        System.out.println(finalMap);
    }
}
public class Java8Example2 {

    public static void main(String[] args) {

        List<Item> items = Arrays.asList(
                new Item("apple", 10, new BigDecimal(23.5)),
                new Item("apple", 20, new BigDecimal(32.5)),
                new Item("orange", 30, new BigDecimal(13.9)),
                new Item("orange", 20, new BigDecimal(33.5)),
                new Item("orange", 10, new BigDecimal(63.5)),
                new Item("orange", 50, new BigDecimal(41.5)),
                new Item("peach", 20, new BigDecimal(26.5)),
                new Item("peach", 30, new BigDecimal(42.5)),
                new Item("peach", 40, new BigDecimal(24.5)),
                new Item("peach", 10, new BigDecimal(12.5))
        );

        // Grouping, counting
        Map<String, Long> counting = items.stream()
                .collect(Collectors.groupingBy(Item::getName, Collectors.counting()));
        System.out.println(counting);

        // Grouping, counting, quantity
        Map<String, Integer> sum = items.stream()
                .collect(Collectors.groupingBy(Item::getName, Collectors.summingInt(Item::getQty)));
        System.out.println(sum);

    }
}

 

4. Interpretation of stream source code

Let's break down this part slowly when we have time. In addition, I will pay attention to the official account Java technology stack, and reply in the background: interview can get my Java series interview questions and answers, which are very complete.

OK, the above is the whole content. If you can insist on seeing here, you must be very fruitful. Then move your little hand to take the offer and point a praise before you go.

Original link: https://blog.csdn.net/mu_wind/article/details/109516995

Keywords: Java

Added by blacksharkmedia on Sun, 19 Dec 2021 10:54:22 +0200