Java 8 uses Stream stream to operate List

Posted by superwormy on Thu, 30 Dec 2021 18:21:19 +0100

Java 8 uses Stream stream to operate List

create object

//user object
public class UserPO {
    @ApiModelProperty(example = "", required = false, value = "Serial number")
    private Integer id;
    @ApiModelProperty(example = "", required = false, value = "full name")
    private String name;
    @ApiModelProperty(example = "", required = false, value = "Gender")
    private String sex;
    @ApiModelProperty(example = "", required = false, value = "Age")
    private Integer age;
    @ApiModelProperty(example = "", required = false, value = "department")
    private String department;
    @ApiModelProperty(example = "", required = false, value = "wages")
    private BigDecimal salary;
    public UserPO(Integer id, String name, String sex, Integer age, String department, BigDecimal salary) {
    this.id = id;
    this.name = name;
    this.sex = sex;
    this.age = age;
    this.department = department;
    this.salary = salary;
}
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getDepartment() {
        return department;
    }

    public void setDepartment(String department) {
        this.department = department;
    }

    public BigDecimal getSalary() {
        return salary;
    }

    public void setSalary(BigDecimal salary) {
        this.salary = salary;
    }
    
    @Override
    public String toString() {
        return "UserPO{" +
                "Serial number=" + id +
                ", full name='" + name + '\'' +
                ", Gender='" + sex + '\'' +
                ", Age=" + age +
                ", department='" + department + '\'' +
                ", wages=" + salary +
                '}';
    }
}

I Grouping method

1.1 groupingBy (common)

Use groupingBy() to group the data and finally return a Map type.
Note: if the collection is empty, exceptions will be thrown during grouping
Example: grouping user lists by Department

/**
 * @Description groupingBy() grouping
 * @Author gzh
 */
@Test
public void groupingByTest(){
    //Get user list
    List<UserPO> userList = getUserList();
    //Group user lists by Department
    Map<String,List<UserPO>> userMap = userList.stream().collect(Collectors.groupingBy(UserPO::getDepartment));
    //Traverse the results after grouping
    userMap.forEach((key, value) -> {
        System.out.println(key + ": ");
        value.forEach(System.out::println);
        System.out.println("-------------------");
    });
}

results of enforcement

1.2 multi level grouping

groupingBy can accept a second parameter to realize multi-level grouping.
Example: group the user list according to department and gender.

/**
 * @Description Multi level grouping using groupingBy()
 * @Author gzh
 */
 @Test
 public void multistageGroupingByTest() {
     //Get user list
     List<UserPO> userList = getUserList();
     //User lists are grouped by department and gender
     Map<String,Map<String,List<UserPO>>> userMap = userList.stream().collect(Collectors.groupingBy(UserPO::getDepartment,Collectors.groupingBy(UserPO::getSex)));
     //Traverse the results after grouping
     userMap.forEach((key1, map) -> {
         System.out.println(key1 + ": ");
         map.forEach((key2,user)->{
             System.out.println(key2 + ": ");
             user.forEach(System.out::println);
         });
         System.out.println("------------------------------");
     });
 }

results of enforcement

1.3 group summary

Example: group by department and summarize the average age of users in each department.

/**
 * @Description Use groupingBy() to group totals
 * @Author gzh
 */
@Test
public void groupCollectTest()    {
    //Get user list
    List<UserPO> userList = getUserList();
    //Group by department and summarize the average age of users in each department
    Map<String, Double> userMap = userList.stream().collect(Collectors.groupingBy(UserPO::getDepartment, Collectors.averagingInt(UserPO::getAge)));
    //Traverse the results after grouping
    userMap.forEach((key, value) -> {
        System.out.println(key + "Average age:" + value);
    });
}

results of enforcement

II Query method

2.1 distinct (common)

Duplicate data can be removed using the distinct() method.
Example: obtain the Department list and remove duplicate data.

/**
 * @Description Use distinct() to remove duplicate data
 * @Author gzh
 */
 @Test
 public void distinctTest() {
     //Get user list
     List<UserPO> userList = getUserList();
     //Get the list of departments and remove duplicate data
     List<String> departmentList = userList.stream().map(UserPO::getDepartment).distinct().collect(Collectors.toList());
     //Traverse Department list
     System.out.println("------Before weight removal------");
     userList.forEach(item->{
         System.out.println(item.getDepartment());
     });
     System.out.println("------After weight removal------");
     departmentList.forEach(System.out::println);
 }

results of enforcement

2.2 limit(long n) and skip(long n)

The limit(long n) method is used to return the first n pieces of data, and the skip(long n) method is used to skip the first n pieces of data.
Example: to obtain the user list, it is required to skip the first three data after the first data.

/**
 * @Description limit(long n)Method is used to return the first n pieces of data. skip(long n) method is used to skip the first n pieces of data
 * @Author gzh
 */
@Test
public void limitAndSkipTest() {
    //Get user list
    List<UserPO> userList = getUserList();
    //To obtain the user list, it is required to skip the first three data after the first data
    userList = userList.stream().skip(1).limit(3).collect(Collectors.toList());
    //Traverse user list
    userList.forEach(System.out::println);
}

results of enforcement

2.3 map (T - > R) (common) and flatmap (T - > stream)

Use map() to map each element T in the stream to R (similar to type conversion).
Note: when the collection is null, no exception will be thrown when using map() to get column elements
Use flatMap() to map each element T in the stream into a stream, and then connect each stream into a stream.
Example: use the map() method to get the name column in the user list.

/**
 * @Description Get column elements using map()
 * @Author gzh
 */
@Test
public void mapTest()    {
    //Get user list
    List<UserPO> userList = getUserList();
    //Get a list of user names
    List<String> nameList = userList.stream().map(UserPO::getName).collect(Collectors.toList());
    //perhaps
    List<Integer> gaeList = userList.stream().map(user -> user.getAge()).collect(Collectors.toList());
    //Traversal name list
    nameList.forEach(System.out::println);
    //Ergodic age
    gaeList.forEach(System.out::println);
}

Array type

//Array type
String[] nameArray = userList.stream().map(UserPO::getName).collect(Collectors.toList()).toArray(new String[userList.size()]);

results of enforcement

Example: use flatMap() to connect each element in the stream into a stream.

/**
 * @Description Use flatMap() to connect each element in the stream into a stream
 * @Author gzh
 */
@Test
public void flatMapTest() {
    //Create city
    List<String> cityList = new ArrayList<String>();
    cityList.add("Beijing; Shanghai; Guangzhou; Shenzhen");
    cityList.add("Suzhou; Wuhan; Hangzhou; Nanjing");
    //Separate the list of cities and use flatMap() to connect each element in the stream into a stream.
    cityList = cityList.stream().map(city -> city.split(";")).flatMap(Arrays::stream).collect(Collectors.toList());
    //Traverse city list
    cityList.forEach(System.out::println);
}

results of enforcement

2.4 filter (T - > Boolean)

Use filter() to filter the list data.
Example: obtain the list of users whose department is "R & D department".

/**
 * @Description Use filter() to filter the list information
 * @Author gzh
 */
@Test
public void filterTest() {
    //Get user list
    List<UserPO> userList = getUserList();
    //Get the list of users whose department is "R & D department"
    userList = userList.stream().filter(user -> user.getDepartment().equals("R & D department")).collect(Collectors.toList());
    //Traverse user list
    userList.forEach(System.out::println);
}

results of enforcement

2.5 findAny() and findFirst()

Use findAny() and findFirst() to get a piece of data.
Example: obtain the user information with the user name called "R & D department". If it is not found, it returns null.

/**
 * @Description Use findAny() to get the first piece of data
 * @Author gzh
 */
@Test
public void findAnytTest() {
    //Get user list
    List<UserPO> userList = getUserList();
    //Get the user information whose user name is called "R & D department". If it is not found, null is returned
    UserPO user = userList.stream().filter(u -> u.getDepartment().equals("R & D department")).findAny().orElse(null);
    //Print user information
    System.out.println(user);
}

results of enforcement

Note: both findFirst() and findAny() obtain the first data in the list, but the elements returned by findAny() operation are uncertain. Calling findAny() multiple times for the same list may return different values. findAny() is used for more efficient performance. If there is less data, the first result will generally be returned in the case of serial. If it is in the case of parallel stream, it cannot be guaranteed to be the first result.
Example: using parallel stream, findAny() does not necessarily return the first piece of data.

UserPO user = userList.parallelStream().filter(u -> u.getDepartment().startsWith("R & D department")).findAny().orElse(null);

Results of multiple executions

III Sorting method

3.1 sorted () / sorted ((T, t) - > int) (common)

If the class of the elements in the Stream implements the Comparable interface, that is, it has its own sorting rules, you can directly call the sorted() method to sort the elements, such as Stream. Instead, you need to call sorted ((T, t) - > int) to implement the Comparator interface.
Example: sort by user age.

/**
 * @Description Sort using sorted()
 * @Author gzh
 */
@Test
public void sortedTest() {
    //Get user list
    List<UserPO> userList = getUserList();
    //Sort by age (ascending)
    userList = userList.stream().sorted(Comparator.comparingInt(UserPO::getAge)).collect(Collectors.toList());
    //Sort by age (in descending order) reversed() is the opposite
    List<UserPO> userLists = userList.stream().sorted(Comparator.comparingInt(UserPO::getAge).reversed()).collect(Collectors.toList());
    //Traverse the user list (in ascending order)
    userList.forEach(System.out::println);
    System.out.println("--------------------");
    //Traverse the user list (in descending order)
    userLists.forEach(System.out::println);
}

results of enforcement

IV Judgment method

4.1 anyMatch(T -> boolean)

Use anymatch (T - > Boolean) to determine whether an element in the flow matches the given t - > Boolean condition.

4.2 allMatch(T -> boolean)

Use allmatch (T - > Boolean) to determine whether all elements in the flow match the given t - > Boolean condition.

4.3 noneMatch(T -> boolean)

Use nonematch (T - > Boolean) to check whether no element in the flow matches the given t - > Boolean condition.
Example: use anyMatch(), allMatch(), and noneMatch().

/**
 * @Description Use anyMatch(), allMatch(), noneMatch()
 * @Author gzh
 */
@Test
public void matchTest() {
    //Get user list
    List<UserPO> userList = getUserList();
    //Judge whether there is data named "Zhang San" in the user list
    boolean result1 = userList.stream().anyMatch(user -> user.getName().equals("Zhang San"));
    //Judge whether the user name contains the "Zhang San" field
    boolean result2 = userList.stream().allMatch(user -> user.getName().contains("Zhang San"));
    //Judge whether the user name does not contain the "Zhang San" field
    boolean result3 = userList.stream().noneMatch(user -> user.getName().contains("Zhang San"));
    //Print results
    System.out.println(result1);
    System.out.println(result2);
    System.out.println(result3);
}

results of enforcement

V statistical method

5.1 counting() and count()

You can use counting() and count() to count the list data.
Example: use count() to count user list information.

/**
 * @Description Use counting() or count()
 * @Author gzh
 */
@Test
public void countTest()    {
    //Get user list
    List<UserPO> userList = getUserList();
    //Count the number of people in the R & D department and use the counting() method
    Long departCount = userList.stream().filter(user -> user.getDepartment().equals("R & D department")).collect(Collectors.counting());
    //Count the number of people over 30 years old, and use the count() method for Statistics (recommended)
    Long ageCount = userList.stream().filter(user -> user.getAge() >= 30).count();
    //Count the number of people whose salary is greater than 1500 yuan
    Long salaryCount = userList.stream().filter(user -> user.getSalary().compareTo(BigDecimal.valueOf(1500)) == 1).count();
    //Print results
    System.out.println("Number of people in R & D department:" + departCount + "people");
    System.out.println("30 Number of persons aged over:" + ageCount + "people");
    System.out.println("Number of employees with salary greater than 1500 yuan:" + salaryCount + "people");
}

results of enforcement

5.2 reduce ((T, t) - > t) and reduce (T, (T, t) - > t)

Use reduce ((T, t) - > t) and reduce (T, (T, t) - > t) to combine elements in the flow, such as summation, quadrature, maximum, etc.
Example: use reduce() to find the maximum, minimum and sum of ages in the user list.

/**
 * @Description Use the reduce() method
 * @Author gzh
 */
@Test
public void reduceTest()    {
    //Get user list
    List<UserPO> userList = getUserList();
    //The maximum, minimum, and sum of ages in the user list
    int maxVal = userList.stream().map(UserPO::getAge).reduce(Integer::max).get();
    int minVal = userList.stream().map(UserPO::getAge).reduce(Integer::min).get();
    int sumVal = userList.stream().map(UserPO::getAge).reduce(0,Integer::sum);
    //Print results
    System.out.println("Maximum age:" + maxVal);
    System.out.println("Minimum age:" + minVal);
    System.out.println("Total age:" + sumVal);
}

results of enforcement

5.3 mapToInt(T -> int) ,mapToDouble(T -> double) ,mapToLong(T -> long)

int sumVal = userList.stream().map(User::getAge).reduce(0,Integer::sum); The method for calculating the sum of elements implies the packing cost. After the map (user:: getage) method changes into the Stream type, and each integer needs to be unpacked into an original type and then summed by the sum method, which greatly affects the efficiency. To solve this problem, Java 8 conscientiously introduces the numerical streams intstream, doublestream and longstream. The elements in this Stream are original data types, namely int, double and long.

Convert stream to numeric stream:
mapToInt(T -> int) : return IntStream
mapToDouble(T -> double) : return DoubleStream
mapToLong(T -> long) : return LongStream
Example: use mapToInt() to find the maximum, minimum, sum and average values of age in the user list.

/**
 * @Description Use mapToInt() method
 * @Author gzh
 */
@Test
public void mapToIntTest()    {
    //Get user list
    List<UserPO> userList = getUserList();
    //Maximum value, minimum value, sum, average value of age in the user list
    int maxVal = userList.stream().mapToInt(UserPO::getAge).max().getAsInt();
    int minVal = userList.stream().mapToInt(UserPO::getAge).min().getAsInt();
    int sumVal = userList.stream().mapToInt(UserPO::getAge).sum();
    double aveVal =  userList.stream().mapToInt(UserPO::getAge).average().getAsDouble();
    //Print results
    System.out.println("Maximum age:" + maxVal);
    System.out.println("Minimum age:" + minVal);
    System.out.println("Total age:" + sumVal);
    System.out.println("average age:" + aveVal);
}

results of enforcement

5.4 summerint(), summerlong(), summerdouble() are used to calculate the sum

Example: calculate the sum of ages

//Calculate the sum of ages
int sumAge = userList.stream().collect(Collectors.summingInt(UserPO::getAge));

5.5 averagingInt(), averagingLong(), and averagingDouble() are used to calculate the average value

Example: calculate the average age

//Calculate average age
double aveAge = userList.stream().collect(Collectors.averagingDouble(UserPO::getAge));

5.6 summarizingInt(),summarizingLong(),summarizingDouble()

These three methods are special. For example, summarizingInt will return IntSummaryStatistics type.
The IntSummaryStatistics class provides methods for calculating the average, total, maximum, minimum and sum, as shown in the following figure:

Example: use IntSummaryStatistics to make statistics: maximum, minimum, sum, average, and total

/**
 * @Description Using summarizingInt statistics
 * @Author gzh
 */
@Test
public void summarizingIntTest()    {
    //Get user list
    List<UserPO> userList = getUserList();
    //Gets the IntSummaryStatistics object
    IntSummaryStatistics ageStatistics = userList.stream().collect(Collectors.summarizingInt(UserPO::getAge));
    //Statistics: maximum, minimum, total, average, total
    System.out.println("Maximum age:" + ageStatistics.getMax());
    System.out.println("Minimum age:" + ageStatistics.getMin());
    System.out.println("Total age:" + ageStatistics.getSum());
    System.out.println("average age:" + ageStatistics.getAverage());
    System.out.println("Total number of employees:" + ageStatistics.getCount());
}

results of enforcement

5.7 statistics of BigDecimal type

For fund related fields, BigDecimal data type is usually used.
Example: Statistics of user salary information.

/**
 * @Description BigDecimal Type statistics
 * @Author gzh
 */
@Test
public void BigDecimalTest(){
    //Get user list
    List<UserPO> userList = getUserList();
    //Maximum salary
    BigDecimal maxSalary = userList.stream().map(UserPO::getSalary).max((x1, x2) -> x1.compareTo(x2)).get();
    //minimum wage 
    BigDecimal minSalary = userList.stream().map(UserPO::getSalary).min((x1, x2) -> x1.compareTo(x2)).get();
    //Total salary
    BigDecimal sumSalary = userList.stream().map(UserPO::getSalary).reduce(BigDecimal.ZERO, BigDecimal::add);
    //Average salary
    BigDecimal avgSalary = userList.stream().map(UserPO::getSalary).reduce(BigDecimal.ZERO, BigDecimal::add).divide(BigDecimal.valueOf(userList.size()), 2, BigDecimal.ROUND_HALF_UP);
    //Print statistics
    System.out.println("Maximum salary:" + maxSalary + "element");
    System.out.println("Minimum salary:" + minSalary + "element");
    System.out.println("Total salary:" + sumSalary + "element");
    System.out.println("Average salary:" + avgSalary + "element");
}

results of enforcement

Topics: Java data structure list