2017-08-22 13 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());