2017-08-22 55 views
3

因此,我有一个包含来自数据库的重复实体的列表,它具有相同的“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覆盖等于哪个监视RealId,如果它们相等,则使用反射来观察其他每个场。

+0

我们不能做一个SQL查询的变化? – vikiiii

+0

是的,我可以改变查询!我使用休眠,所以我想我可以做一个查询,不会选择重复 – baskwo

回答

4

试试这个:

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并将其收集到List

+3

你能解释你的方法吗?这将比仅*代码*答案更有用。 – Zabuza

+0

使用Hibernate和H2嵌入式数据库,最好是“getAll”,然后使用你的方法或做一个相同的查询? – baskwo

+0

@baskwo - 这就是你实现getAll的实体 –

0

没有java8功能性的东西:

Map<Long, Item> map = new HashMap<>(); 
    for (Item item: items) { 
     Item old = map.get(item.getId()); 
     if (old == null || old.getDate().before(item.getDate())) { 
      map.put(item.getId(), item); 
     } 
    } 

    List<Item> result = new ArrayList<Item>(map.values());