I have to say that using the Java Stream operation set is extremely useful, but recently when I looked at the production environment error log, I occasionally saw the following two exceptions:

  1. java.lang.NullPointerException
  2. java.util.NoSuchElementException

So this blog post summarizes some scenarios for using Java Stream and how to avoid the above two exceptions:

  1. Extract a column in a collection (plain extract, de-weigh)
  2. Filter collections by conditions
  3. sum
  4. Maximum/minimum/average value

1. Data preparation

Let’s first define the Friend class:

package com.zwwhnly.springbootaction.model;

import lombok.Data;

import java.math.BigDecimal;

@Data
public class Friend {
    /** * name */
    private String name;

    /** * age */
    private Integer age;

    /** * Height */
    private Long height;

    /** ** City */
    private String city;

    /** * Weight */
    private BigDecimal weight;

    public Friend(String name, Integer age, Long height, String city, BigDecimal weight) {
        this.name = name;
        this.age = age;
        this.height = height;
        this.city = city;
        this.weight = weight; }}Copy the code

Then initialize the following data for later use:

public static List<Friend> getFriendList(a) {
    List<Friend> friendList = new ArrayList<>();
    friendList.add(new Friend("Chou".28.175L."Zhengzhou".new BigDecimal("101.5")));
    friendList.add(new Friend("Xiao wu".28.170L."Luoyang".new BigDecimal("111.5")));
    friendList.add(new Friend("Zheng".29.176L."Zhengzhou".new BigDecimal("121.5")));
    friendList.add(new Friend("Wang".29.180L."Beijing".new BigDecimal("130")));
    friendList.add(new Friend("Xiao zhao.".27.178L."Suzhou".new BigDecimal("140")));
    friendList.add(new Friend("Money".null.null."Hangzhou".new BigDecimal("150")));

    return friendList;
}
Copy the code

2. Extract a column from the collection

2.1 General Extraction

For example, if we need to extract the names of all our friends, we can use the Stream map() method, which looks like this:

List<Friend> friendList = getFriendList();
List<String> nameList = friendList.stream().map(Friend::getName).collect(Collectors.toList());

nameList.forEach(name -> System.out.println(name));
Copy the code

Output result:

Small weeks

Xiao wu

zheng

wang

Xiao zhao

2.2 Weight removal after extraction

For example, if we want to extract the ages of all our friends, but we want to de-duplicate them, we can use the Stream distinct() method, which looks like this:

List<Friend> friendList = getFriendList();
List<Integer> ageList = friendList.stream().map(Friend::getAge).distinct().collect(Collectors.toList());

ageList.forEach(age -> System.out.println(age));
Copy the code

Output result:

28

29

27

3. Filter sets based on conditions

For example, if we need to get all our friends under 29 years old and above 170 years old, we can call the filter method and implement the code as follows:

List<Friend> friendList = getFriendList(); List<Friend> youngPeople = friendList.stream() .filter(friend -> friend.getAge() ! =null && friend.getAge() < 29&& friend.getHeight() ! =null && friend.getHeight() > 170L)
        .collect(Collectors.toList());
System.out.println(youngPeople);
Copy the code

Output result:

Friend(name= 0, age= 0, height= 0, city= 0, weight= 0)

Friend(name= name, age=27, height=178, city= suzhou, weight=140)

4. The sum

4.1 the Integer, Long, Double

For example, if we need to calculate the sum of all our friends’ ages, we can call the mapToInt method as follows:

List<Friend> friendList = getFriendList();

intageSum = friendList.stream().filter(friend -> friend.getAge() ! =null).mapToInt(Friend::getAge).sum();
System.out.println(ageSum);
Copy the code

Output result:

141

Matters needing attention:

Because our age field defines the wrapper type Integer, but the sum returns the basic type int, we must filter out data of null age before calling mapToInt, otherwise we will throw exceptions every minute.

For example, we add a null age:

friendList.add(new Friend("Money".null.178."Hangzhou"));
Copy the code

Then, we filter null data, not directly call mapToInt method, will be thrown. Java lang. NullPointerException:

List<Friend> friendList = getFriendList();

int ageSum = friendList.stream().mapToInt(Friend::getAge).sum();
System.out.println(ageSum);
Copy the code

If the field type is Long or Double, the corresponding mapToDouble and mapToLong can be called as follows:

4.2 BigDecimal

Unlike Integer, Long, and Double, if the field type is BigDecimal, the sum calls the reduce method as follows:

List<Friend> friendList = getFriendList(); BigDecimal weightSum = friendList.stream() .filter(friend -> friend.getWeight() ! =null)
        .map(Friend::getWeight)
        .reduce(BigDecimal.ZERO, BigDecimal::add);
System.out.println(weightSum);
Copy the code

Output result:

754.5

Matters needing attention:

In order to avoid the Java. Lang. NullPointerException, in the code above. The filter (friend – > friend. GetWeight ()! = null) also remember to add.

5. Maximum/minimum/average

5.1 the Integer, Long, Double

For example, if we need to get the maximum height of all our friends, the code looks like this:

List<Friend> friendList = getFriendList();

longheightMax = friendList.stream() .filter(friend -> friend.getHeight() ! =null)
        .mapToLong(Friend::getHeight)
        .max().orElse(0);
System.out.println(heightMax);
Copy the code

Output result:

180

Matters needing attention:

Since the Max () method returns OptionalLong, we need to continue calling orElse() to set the default value. Don’t use getAsLong() directly here, because when the collection is empty, Sell. You must have met the Java util. NoSuchElementException anomaly:

longheightMax = friendList.stream() .filter(friend -> friend.getHeight() ! =null)
        .mapToLong(Friend::getHeight)
        .max().getAsLong();
Copy the code

OrElse () :

public long orElse(long other) {
    return isPresent ? value : other;
}
Copy the code

GetAsLong () :

public long getAsLong(a) {
    if(! isPresent) {throw new NoSuchElementException("No value present");
    }
    return value;
}
Copy the code

Similarly, the code to get the minimum value looks like this:

List<Friend> friendList = getFriendList();

longheightMin = friendList.stream() .filter(friend -> friend.getHeight() ! =null)
        .mapToLong(Friend::getHeight)
        .min().orElse(0);
System.out.println(heightMin);
Copy the code

The code to obtain the average is as follows:

List<Friend> friendList = getFriendList();

doubleheightAverage = friendList.stream() .filter(friend -> friend.getHeight() ! =null)
    .mapToLong(Friend::getHeight)
    .average().orElse(0D);
System.out.println(heightAverage);
Copy the code

5.2 BigDecimal

For example, if we want to get the maximum weight of all our friends, the code looks like this:

List<Friend> friendList = getFriendList(); BigDecimal weightMax = friendList.stream() .filter(friend -> friend.getWeight() ! =null)
        .map(Friend::getWeight)
        .max(BigDecimal::compareTo)
        .orElse(BigDecimal.ZERO);
System.out.println(weightMax);
Copy the code

Output result:

150

Matters needing attention:

1) to avoid the Java. Lang. NullPointerException, attention to the data filter weight is null

2) Since the Max () method returns an Optional value, we need to continue calling orElse() to set a default value. Do not use get() directly, because when the collection is empty, Sell. You must have met the Java util. NoSuchElementException anomaly:

BigDecimal weightMax = friendList.stream() .filter(friend -> friend.getWeight() ! =null)
        .map(Friend::getWeight)
        .max(BigDecimal::compareTo)
        .get();
Copy the code

The get() method looks like this:

public T get(a) {
    if (value == null) {
        throw new NoSuchElementException("No value present");
    }
    return value;
}
Copy the code

Similarly, the code to get the minimum value looks like this:

List<Friend> friendList = getFriendList(); BigDecimal weightMax = friendList.stream() .filter(friend -> friend.getWeight() ! =null)
        .map(Friend::getWeight)
        .min(BigDecimal::compareTo)
        .orElse(BigDecimal.ZERO);
System.out.println(weightMax);
Copy the code

6. Summary

Using Java Stream collection operation is very convenient, but still easy to step on some pits, such as Java mentioned in the article. Lang. NullPointerException and Java. Util. NoSuchElementException abnormalities, so should pay attention when using, Can not step on the pit do not step on the pit, even if step on the pit, do not step on the same pit many times.


Note: If you think this blog has any mistakes or better suggestions, please leave a comment, I will follow up and correct the blog content in time!