遇到这样一个问题,一个实体类集合, 该集合需要根据姓名剔除重复的值,要求保留重复值中时间最新的那一条数据(去重并按时间排序取第一条)
解决问题的思路记录如下:
- 根据姓名进行元素的分组,每一组是相同名字的集合元素
- 排序每一组中的元素根据时间降序排列
- 依次获取每组当中的第一个元素
代码解决
java 中提供了 stream 流可以很方便的解决分组,排序问题,下面提供 demo 代码如下记录:
//定义一个新集合,放置去重后的值
List<User> filterUser = new ArrayList<>();
// 根据名字分组用户
Map<String,List<User>> groupByUsers = users.stream().
collect(Collectors.groupingBy(User::getName));
Set<Map.Entry<String,List<User>>> enties = groupByUsers.entrySet();
for (Map.Entry<String,List<User>> entry : enties) {
// 获取每一个分组用户
List<User> values = entry.getValue();
// 每一个组中就一个元素的时候,不用排序
if (values.size() == 1)
filterUser.addAll(values);
else{
// 获取第一个值,根据时间降序排列
User firstUser = values.stream().sorted(Comparator.comparing(User::getBirthday).reversed()).findFirst().get();
filterUser.add(firstUser);
}
}
sql 解决
具体解决方案参考一篇文章
关键性 sql 记录如下:
select t.*
from (select a.*, row_number() over(partition by col1需要分组的字段 order by col2更新时间 desc) rw
from 表 a) t
where t.rw = 1
row_number()over(partition by col1 order by col2)表示根据col1分组,在分组内部根据col2排序,而此函数计算的值就表示每组内部排序后的顺序编号(组内连续的唯一的)。