用Stream流操作List集合去除重复对象的重复属性
概要
日常开发中,我们可能会遇到这样一种情况,需要对数据库查询出来的数据进行一个二次处理,从而达到我们需要的数据结构。
正文
List<UserInfo> list = new ArrayList<>();
UserInfo u1 = new UserInfo();
u1.setUserName("测试员工").setUserStatus("1");
UserInfo u2 = new UserInfo();
u2.setUserName("员工").setUserStatus("1");
UserInfo u3 = new UserInfo();
u3.setUserName("员工").setUserStatus("0");
UserInfo u4 = new UserInfo();
u4.setUserName("测试员工").setUserStatus("0");
UserInfo u5 = new UserInfo();
u5.setUserName("测试员工1").setUserStatus("1");
UserInfo u6 = new UserInfo();
u6.setUserName("测试员工1").setUserStatus("0");
CollectionUtils.addAll(list, new UserInfo[]{u1, u2, u3, u4, u5, u6});
/**
* 1. 根据用户名分组并统计数量
* 2. 取出数量大于1的用户姓名
*/
List<String> collect = list.stream().collect(Collectors.groupingBy(UserInfo::getUserName, Collectors.counting())).entrySet()
.stream().filter(entry -> entry.getValue() > 1).map(Map.Entry::getKey).collect(Collectors.toList());
// 去重并重新设置userStatus的值
if (CollectionUtils.isNotEmpty(collect)){
collect.forEach(s -> distinctUserInfo(collect,s));
}
private void distinctUserInfo(List<UserInfo> list, String repeatName) {
// 先取出来第一个
Optional<UserInfo> first = list.stream().filter(userInfo -> userInfo.getUserName().equals(repeatName)).findFirst();
// 再取出与之对应重复的
List<UserInfo> collect = list.stream().filter(userInfo -> userInfo.getUserName().equals(repeatName)).collect(Collectors.toList());
if (first.isPresent()) {
UserInfo userInfo = first.get();
// 进行相关处理
if (CollectionUtils.isNotEmpty(collect)){
List<String> collect1 = collect.stream()
.map(UserInfo::getUserStatus).collect(Collectors.toList());
StringBuilder stringBuilder = new StringBuilder();
collect1.forEach(stringBuilder::append);
userInfo.setUserStatus(stringBuilder.toString());
}
// 先将所有符合这个重复的userName的对象从源集合中删除
list.removeIf(next -> next.getUserName().equals(repeatName));
//再将取出来的第一个添加进去
list.add(userInfo);
}
}
输出结果
// 伪代码,无需验证实用性
userInfo{userName: 测试员工,userStatus: 10}
userInfo{userName: 员工,userStatus: 10}
userInfo{userName: 测试员工1,userStatus: 10}
原理讲解
统计每个userName出现的次数, 然后通过Stream的filter将出现次数大于1的值放到list中.最后通过遍历将集合中所有userName等于重复userName的对象删除,然后再把进行处理过后的对象添加进去,这样就完成了对某一个值重复的对象的相关处理。