Nicolas Sagala Beaucage
Nicolas Sagala Beaucage

Reputation: 1297

Set created from complex List

So I have a list containing duplicated entities from database with the same "Id" (it's not the real Id but kind of) but a different CreatedDate.

So I would like to have the latest entity from duplicates with the latest CreatedDate.

Example I have a list of created users :

RealId|CreatedDate|Id|Name
1|20170101|1|User1
2|20170102|1|User1Modified
3|20170103|2|User2
4|20170104|2|User2Modified

From that list what is the best way to obtain :

RealId|CreatedDate|Id|Name
2|20170102|1|User1Modified
4|20170104|2|User2Modified

This is my first idea

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());

An other idea I have is to make it order descending by the date then do distinct().collect() like :

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());

Here, T overrides equals which watch for the RealId if they are equal else use reflection to watch every other field.

Upvotes: 3

Views: 88

Answers (2)

algrid
algrid

Reputation: 5954

Without java8 functional stuff:

    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());

Upvotes: 0

Schidu Luca
Schidu Luca

Reputation: 3947

Try this:

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());

Here is used Collectors.groupingBy to create a Map<Integer, Optional<YourObject>>, grouped by id and most recent createDate. The you get the entrySet for this map and collect it to a List.

Upvotes: 4

Related Questions