使⽤JavaStream,提取集合中的某⼀列按条件过滤集合求和最⼤值最⼩值平均
值
不得不说,使⽤Java Stream操作集合实在是太好⽤了,不过最近在观察⽣产环境错误⽇志时,发现偶尔会出现以下2个异常:
1. java.lang.NullPointerException
2. java.util.NoSuchElementException
因此本篇博客总结下使⽤Java Stream的部分场景以及如何避免上述的2个异常:
1. 提取集合中的某⼀列(普通提取、去重)
2. 按条件过滤集合
3. 求和
4. 最⼤值/最⼩值/平均值
1. 数据准备
⾸先定义下Friend类:
package com.del;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class Friend {
/**
* 姓名
*/
private String name;
/**
* 年龄
*/
private Integer age;
/**
* ⾝⾼
*/
private Long height;
/**
* 所在城市
*/
private String city;
/
**
* 体重
*/
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;
}
}
然后初始化以下数据供后⾯使⽤:
public static List<Friend>getFriendList(){
List<Friend> friendList =new ArrayList<>();
friendList.add(new Friend("⼩周",28,175L,"郑州",new BigDecimal("101.5")));
friendList.add(new Friend("⼩吴",28,170L,"洛阳",new BigDecimal("111.5")));
friendList.add(new Friend("⼩郑",29,176L,"郑州",new BigDecimal("121.5")));
friendList.add(new Friend("⼩王",29,180L,"北京",new BigDecimal("130")));
friendList.add(new Friend("⼩赵",27,178L,"苏州",new BigDecimal("140")));
friendList.add(new Friend("⼩钱", null, null,"杭州",new BigDecimal("150")));
return friendList;
}
2. 提取集合中的某⼀列
2.1 普通提取
⽐如,我们需要提取出所有朋友的姓名,可以使⽤Stream的map()⽅法,实现代码如下所⽰:
List<Friend> friendList =getFriendList();
List<String> nameList = friendList.stream().map(Friend::getName).List());
nameList.forEach(name -> System.out.println(name));
输出结果:
⼩周
bigdecimal转换为integer⼩吴
⼩郑
⼩王
⼩赵
2.2 提取后去重
⽐如,我们需要提取出所有朋友的年龄,但是需要去重,可以使⽤Stream的distinct()⽅法,实现代码如下所⽰:
List<Friend> friendList =getFriendList();
List<Integer> ageList = friendList.stream().map(Friend::getAge).distinct().List());
ageList.forEach(age -> System.out.println(age));
输出结果:
28
29
27
3. 按条件过滤集合
⽐如,我们需要获取所有朋友中年龄在29岁以下,并且⾝⾼在170以上的朋友,可以调⽤filter⽅法,实现代码如下所⽰:List<Friend> friendList =getFriendList();
List<Friend> youngPeople = friendList.stream()
.filter(friend -> Age()!= null && Age()<29&&
.List());
System.out.println(youngPeople);
输出结果:
Friend(name=⼩周, age=28, height=175, city=郑州, weight=101.5)
Friend(name=⼩赵, age=27, height=178, city=苏州, weight=140)
4. 求和
4.1 Integer,Long,Double
⽐如,我们需要计算出所有朋友的年龄之和,可以调⽤mapToInt⽅法,实现代码如下所⽰:
List<Friend> friendList =getFriendList();
int ageSum = friendList.stream().filter(friend -> Age()!= null).mapToInt(Friend::getAge).sum();
System.out.println(ageSum);
输出结果:
141
注意事项:
因为我们的age字段定义的是包装类型Integer,但求和之后的返回类型为基本类型int,所以在调⽤mapToInt⽅法之前,⼀定要过滤掉年龄为null的数据,否则分分钟抛异常。
⽐如,我们添加⼀条年龄为null的数据:
friendList.add(new Friend("⼩钱",null,178,"杭州"));
然后,我们不过滤null数据,直接调⽤mapToInt⽅法,就会抛出java.lang.NullPointerException异常:
List<Friend> friendList =getFriendList();
int ageSum = friendList.stream().mapToInt(Friend::getAge).sum();
System.out.println(ageSum);
如果字段类型是Long或者Double,可以调⽤相应的mapToDouble、mapToLong,如下所⽰:
4.2 BigDecimal
和Integer、Long、Double类型不同,如果字段类型是BigDecimal,求和的话需要调⽤reduce⽅法,使⽤⽅法如下所⽰:
List<Friend> friendList =getFriendList();
BigDecimal weightSum = friendList.stream()
.filter(friend -> Weight()!= null)
.map(Friend::getWeight)
.reduce(BigDecimal.ZERO, BigDecimal::add);
System.out.println(weightSum);
输出结果:
754.5
注意事项:
为避免java.lang.NullPointerException异常,上⾯代码中的.filter(friend -> Weight() != null)也要记得加。
5. 最⼤值/最⼩值/平均值
5.1 Integer,Long,Double
⽐如,我们需要获取所有朋友中⾝⾼的最⼤值,实现代码如下所⽰:
List<Friend> friendList =getFriendList();
long heightMax = friendList.stream()
.filter(friend -> Height()!= null)
.mapToLong(Friend::getHeight)
.max().orElse(0);
System.out.println(heightMax);
输出结果:
180
注意事项:
因为max()⽅法的返回值是OptionalLong类型,所以我们需要继续调⽤orElse()⽅法设置个默认值,这⾥不要直接使⽤getAsLong()⽅法,因为当集合为空时,会抛出你肯定遇到过的java.util.NoSuchElementException异常:
long heightMax = friendList.stream()
.filter(friend -> Height()!= null)
.mapToLong(Friend::getHeight)
.max().getAsLong();
orElse()源码如下所⽰:
public long orElse(long other){
return isPresent ? value : other;
}
getAsLong()源码如下所⽰:
public long getAsLong(){
if(!isPresent){
throw new NoSuchElementException("No value present");
}
return value;
}
类似地,获取最⼩值的代码如下所⽰:
List<Friend> friendList =getFriendList();
long heightMin = friendList.stream()
.filter(friend -> Height()!= null)
.mapToLong(Friend::getHeight)
.min().orElse(0);
System.out.println(heightMin);
获取平均值的代码如下所⽰:
List<Friend> friendList =getFriendList();
double heightAverage = friendList.stream()
.filter(friend -> Height()!= null)
.mapToLong(Friend::getHeight)
.
average().orElse(0D);
System.out.println(heightAverage);
5.2 BigDecimal
⽐如,我们需要获取所有朋友中体重的最⼤值,实现代码如下所⽰:
List<Friend> friendList =getFriendList();
BigDecimal weightMax = friendList.stream()
.filter(friend -> Weight()!= null)
.map(Friend::getWeight)
.max(BigDecimal::compareTo)
.orElse(BigDecimal.ZERO);
System.out.println(weightMax);
输出结果:
150
注意事项:
1)为避免出现java.lang.NullPointerException异常,注意过滤体重为null的数据
2)因为max()⽅法的返回值为Optional类型,所以我们需要继续调⽤orElse()⽅法设置个默认值,这⾥不要直接使⽤get()⽅法,因为当集合为空时,会抛出你肯定遇到过的java.util.NoSuchElementException异常:
BigDecimal weightMax = friendList.stream()
.filter(friend -> Weight()!= null)
.map(Friend::getWeight)
.max(BigDecimal::compareTo)
.get();
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论