Java jdk1.8新增的Stream流常用的方法

本文详细介绍了如何在Java中使用Stream API进行User实体类的去重、排序和过滤操作,包括基础方法、根据属性去重、多级排序以及各种条件判断。同时,对比了Optional类findAny和findFirst的区别,并探讨了在并行流中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述

User实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {

    private String name;

    private Integer age;

}

	// 创建集合
	List<User> users = new ArrayList<>();
	users.add(new User("张三", 18));
	users.add(new User("李四", 22));
	users.add(new User("王五", 26));

List

去重

基础去重

List<User> collect = users.stream().distinct().collect(Collectors.toList());

根据指定属性去重

// 根据 name 去重
List<User> collect = users.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(User::getName))), ArrayList::new));
// 根据 name和age 去重
List<User> collect = users.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(user -> user.getName() + "-" + user.getAge()))), ArrayList::new));

排序

基础排序


List<Integer> list = Arrays.asList(1,2,3,4);
// 正序
List<Integer> list = list.stream().sorted().collect(Collectors.toList());
// 倒序
List<Integer> list = list.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());

根据指定属性排序

// age 正序
List<User> collect = users.stream().sorted(Comparator.comparing(User::getAge)).collect(Collectors.toList());
// age 倒序
List<User> collect = users.stream().sorted(Comparator.comparing(User::getAge).reversed()).collect(Collectors.toList());

属性有NULL值排序

// null 值排在最后面
List<User> collect = users.stream().sorted(Comparator.comparing(User::getAge,Comparator.nullsLast(Integer::compareTo))).collect(Collectors.toList());
// null 值排在最前面
List<User> collect = users.stream().sorted(Comparator.comparing(User::getAge,Comparator.nullsLast(Integer::compareTo))).collect(Collectors.toList());

指定多个属性分别排序

// age正序 gender正序
List<User> collect = users.stream().sorted(Comparator.comparing(User::getAge).thenComparing(User::getGender)).collect(Collectors.toList());
// age倒序 gender正序
List<User> collect = users.stream().sorted(Comparator.comparing(User::getAge).reversed().thenComparing(User::getGender)).collect(Collectors.toList());

过滤

// 过滤 name!=null 
users.stream().filter(user -> user.getName()!=null).collect(Collectors.toList());

分页

// 第1页,每页10 分页 
long skipNum = (long) (页码 - 1) * 每页数量;
users.stream().skip(skipNum).limit(每页数量).collect(Collectors.toList());

分组

// 根据 age 分组
Map<Integer, List<User>> collect = users.stream().collect(Collectors.groupingBy(User::getAge));
// 根据 age 分组,用 name 作为值
Map<Integer, String> collect = users.stream().collect(Collectors.groupingBy(User::getAge,Collectors.mapping(User::getName, Collectors.toList())));

获取指定属性的集合

// 获取 name 的集合
List<String> users = users.stream().map(User::getName).collect(Collectors.toList());

Map、List互转

使用(key1,key2)->key2表达式用于解决key重复问题;(key1,key2)->key2 表示key重复使用key2覆盖前面的,也可以保留key1的值。

// list转map(name作为key,user对象作为value)   
Map<String, User> userMap = users.stream().collect(Collectors.toMap(User::getName, Function.identity(), (key1, key2) -> key2));
// list转map(name作为key,age作为value)
Map<String, Integer> userMap = users.stream().collect(Collectors.toMap(User::getName, User::getAge));
// map转list
List<User> users = userMap.entrySet().stream().map(Map.Entry::getValue).collect(Collectors.toList());

根据指定字符拼接成字符串

Collectors.joining(分隔符,前缀,后缀)

String str = users.stream().map(User::getName).collect(Collectors.joining("/","(",")"));

最大值、最小值、求和、总条数

// 最大值
int max = users.stream().mapToInt(User::getAge).summaryStatistics().getMax();
Integer maxAge = users.stream().map(User::getAge).max(Integer::compare).get();
// 最小值
int min = users.stream().mapToInt(User::getAge).summaryStatistics().getMin();
Integer mixAge = users.stream().map(User::getAge).min(Integer::compare).get();
// 求和
long sum = users.stream().mapToInt(User::getAge).summaryStatistics().getSum();
Integer sumAge = users.stream().mapToInt(User::getAge).sum();
// 总条数
long count = users.stream().mapToInt(User::getAge).summaryStatistics().getCount();
long count1 = users.stream().count();

判断

检查是否至少匹配一个元素 anyMatch()

有一个年龄大于20的就返回true

boolean bool = users.stream().anyMatch(user -> user.getAge()>20);

检查是否所有值都匹配 allMatch()

全部年龄都大于20才返回true

boolean bool = users.stream().allMatch(user -> user.getAge()>20);

检查是否没有一项匹配 noneMatch()

全部年龄都不大于20才返回true

boolean bool = users.stream().noneMatch(user -> user.getAge()>20);

查找符合条件的第一个元素 findAny()

返回第一个年龄大于20的

Optional<User> userOptional=users.stream().filter(user -> user.getAge() > 20).findAny()

查找符合条件的第一个元素 findFirst()

返回第一个年龄大于20的

Optional<User> userOptional=users.stream().filter(user -> user.getAge() > 20).findFirst()

Optional类

Optional类是一个容器类,也是jdk1.8之后的新特性,代表一个值存在或者不存在。在上面的代码中findAny和findFirst可能上面元素都没找到。java8引入了Optional是为了避免出现null值的问题。
Optional对象.get()就可以获取到user对象。

findAny和findFirst区别

并行流处理,找到第一个元素在并行时限制更多。如果不关心返回的元素是哪个,使用findAny即可。
普通流listUser.stream()和并行流listUser.parallelStream()。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LOVE_DDZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值