list stream 最大和最小值_使用Java Stream,提取集合中的某一列/按条件过滤集合/求和/最大值/最小值/平均值...

不得不说,使用Java Stream操作集合实在是太好用了,不过最近在观察生产环境错误日志时,发现偶尔会出现以下2个异常:

java.lang.NullPointerException

java.util.NoSuchElementException

因此本篇博客总结下使用Java Stream的部分场景以及如何避免上述的2个异常:

提取集合中的某一列(普通提取、去重)

按条件过滤集合

求和

最大值/最小值/平均值

1. 数据准备

首先定义下Friend类:

package com.zwwhnly.springbootaction.model;

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 getFriendList() {

List 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 friendList = getFriendList();

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

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

输出结果:

小周

小吴

小郑

小王

小赵

2.2 提取后去重

比如,我们需要提取出所有朋友的年龄,但是需要去重,可以使用Stream的distinct()方法,实现代码如下所示:

List friendList = getFriendList();

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

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

输出结果:

28

29

27

3. 按条件过滤集合

比如,我们需要获取所有朋友中年龄在29岁以下,并且身高在170以上的朋友,可以调用filter方法,实现代码如下所示:

List friendList = getFriendList();

List youngPeople = friendList.stream()

.filter(friend -> friend.getAge() != null && friend.getAge() < 29 &&

friend.getHeight() != null && friend.getHeight() > 170L)

.collect(Collectors.toList());

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 friendList = getFriendList();

int ageSum = friendList.stream().filter(friend -> friend.getAge() != 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 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 friendList = getFriendList();

BigDecimal weightSum = friendList.stream()

.filter(friend -> friend.getWeight() != null)

.map(Friend::getWeight)

.reduce(BigDecimal.ZERO, BigDecimal::add);

System.out.println(weightSum);

输出结果:

754.5

注意事项:

为避免java.lang.NullPointerException异常,上面代码中的.filter(friend -> friend.getWeight() != null)也要记得加。

5. 最大值/最小值/平均值

5.1 Integer,Long,Double

比如,我们需要获取所有朋友中身高的最大值,实现代码如下所示:

List friendList = getFriendList();

long heightMax = friendList.stream()

.filter(friend -> friend.getHeight() != 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 -> friend.getHeight() != 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 friendList = getFriendList();

long heightMin = friendList.stream()

.filter(friend -> friend.getHeight() != null)

.mapToLong(Friend::getHeight)

.min().orElse(0);

System.out.println(heightMin);

获取平均值的代码如下所示:

List friendList = getFriendList();

double heightAverage = friendList.stream()

.filter(friend -> friend.getHeight() != null)

.mapToLong(Friend::getHeight)

.average().orElse(0D);

System.out.println(heightAverage);

5.2 BigDecimal

比如,我们需要获取所有朋友中体重的最大值,实现代码如下所示:

List friendList = getFriendList();

BigDecimal weightMax = friendList.stream()

.filter(friend -> friend.getWeight() != 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 -> friend.getWeight() != null)

.map(Friend::getWeight)

.max(BigDecimal::compareTo)

.get();

get()方法源码如下所示:

public T get() {

if (value == null) {

throw new NoSuchElementException("No value present");

}

return value;

}

类似地,获取最小值的代码如下所示:

List friendList = getFriendList();

BigDecimal weightMax = friendList.stream()

.filter(friend -> friend.getWeight() != null)

.map(Friend::getWeight)

.min(BigDecimal::compareTo)

.orElse(BigDecimal.ZERO);

System.out.println(weightMax);

6. 总结

使用Java Stream操作集合非常便利,但还是容易踩一些坑,比如文中提到的java.lang.NullPointerException异常和java.util.NoSuchElementException异常,所以使用时要多多注意,能不踩坑就不踩坑,就算踩坑,也别多次踩同一个坑。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要计算集合BigDecimal类型字段的总和,可以使用stream流和reduce方法。首先,将集合转换为流,然后使用map方法将每个对象的BigDecimal字段提取出来。接下来,使用reduce方法将所有的BigDecimal值相加起来。下面是一个示例代码: ```java BigDecimal sum = list.stream() .map(MyClass::getBigDecimalField) .reduce(BigDecimal.ZERO, BigDecimal::add); ``` 在这个示例,假设集合的元素类型为MyClass,其包含一个名为getBigDecimalField的方法,用于获取BigDecimal类型的字段值。reduce方法的第一个参数是初始值,这里使用BigDecimal.ZERO表示初始值为0。第二个参数是一个BinaryOperator,用于将两个BigDecimal值相加。 请注意,你需要根据实际情况将示例代码的MyClass替换为你的实体类名称,getBigDecimalField替换为你的实体类获取BigDecimal字段值的方法名称。 #### 引用[.reference_title] - *1* *2* [java集合最大值平均值以及总和计算问题(BigDecimal类型)](https://blog.csdn.net/weixin_43967890/article/details/121157321)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [List使用Stream流进行集合Collection的各种运算汇总:对BigDecimal求和,某个字段的和、最大值最小值、...](https://blog.csdn.net/weixin_32516271/article/details/113558795)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值