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:
- java.lang.NullPointerException
- java.util.NoSuchElementException
So this blog post summarizes some scenarios for using Java Stream and how to avoid the above two exceptions:
- Extract a column in a collection (plain extract, de-weigh)
- Filter collections by conditions
- sum
- 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!