Filter list of custom object by specific object field

79 views Asked by At

I have an object Batch (String id, Instant date, Long version)

I have a list of Batch and I want to filter to keep one batch for each id where version is the highest i.e:

batch1 = Batch(1, date, 5)
batch2 = Batch(2, date, 4)
batch3 = Batch(2, date, 7)
batch4 = Batch(1, date, 2)
batch5 = Batch(1, date, 4)
batch6 = Batch(3, date, 2)

after filtering I need to have 
List.of(batch1, batch3, batch6)```
2

There are 2 answers

0
Youcef LAIDANI On BEST ANSWER

You can use stream with toMap like this:

Collection<Batch> highestVersionBatches = batches.stream()
        .collect(Collectors.toMap(
                Batch::getId,
                batch -> batch,
                (e, r) -> e.getVersion() >= r.getVersion() ? e : r //<-- magic is here
        )).values();
Outputs
Batch(1, 2023-11-07, 5)
Batch(2, 2023-11-07, 7)
Batch(3, 2023-11-07, 2)

If you want to get List instead of Collection, you can simply use:

List<Batch> result = new ArrayList<>(highestVersionBatches);
0
prasad_ On

Here is a solution with some variation in coding:

List<Batch> result = 
    Stream.of(batch1, batch2, batch3, batch4, batch5, batch6)
            .collect(groupingBy(
                        Batch::getId,
                        maxBy(Comparator.comparing(Batch::getVersion))
            ))
            .values()
            .stream()
            .collect(mapping(Optional::get, toList()));