所以我有一个列表,其中包含来自数据库的重复实体,这些实体具有相同的“Id”(它不是真实的 Id,但有点像)但 CreatedDate 不同。
所以我想从具有最新 CreatedDate 的副本中获取最新的实体。
示例我有一个已创建用户的列表:
RealId|CreatedDate|Id|Name
1|20170101|1|User1
2|20170102|1|User1Modified
3|20170103|2|User2
4|20170104|2|User2Modified
从该列表中获取的最佳方法是什么:
RealId|CreatedDate|Id|Name
2|20170102|1|User1Modified
4|20170104|2|User2Modified
这是我的第一个想法
List<T> r = query.getResultList();
Set<T> distinct = r.stream().filter(x -> {
List<T> clones = r.stream()
.filter(y -> y.getId() == x.getId())
.collect(Collectors.toList());
T max = clones.stream()
.max(Comparator.comparing(AbstractEntityHistory::getEntryDate))
.get();
return max.getNumber() == x.getNumber();
}).collect(Collectors.toSet());
我的另一个想法是让它按日期降序排列,然后像这样执行 distinct().collect() :
Set<T> distinct2 = r.stream().sorted((x,y) -> {
if(x.getEntryDate().isBefore(y.getEntryDate())) {
return 1;
} else if(x.getEntryDate().isAfter(y.getEntryDate())) {
return -1;
} else {
return 0;
}
}).distinct().collect(Collectors.toSet());
在这里,T 覆盖 equals,如果它们相等则监视 RealId,否则使用反射来监视所有其他字段。
最佳答案
试试这个:
List<YourObject> collect = activities
.stream()
.collect(Collectors.groupingBy(
YourObject::getId,
Collectors.maxBy(Comparator.comparing(YourObject::getCreatedDate))))
.entrySet()
.stream()
.map(e -> e.getValue().get())
.collect(Collectors.toList());
这里使用了Collectors.groupingBy
创建一个 Map<Integer, Optional<YourObject>>
, 按 id
分组和最近的 createDate
.你得到 entrySet
对于这张 map 并将其收集到 List
.
关于java - 从复杂列表创建的集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45825784/