Java 8 stream api key based merging

Andrey

I've recently started to learn stream API. I am trying remove duplication from following piece of code. Is it possible use merge function based on Predicate or condition? (Also I was thinking about using partitioningBy or groupingBy from Collectors)

BinaryOperator<LocalDateTime> latestDate = (p, a) -> a.isAfter(p) ? a : p;
BinaryOperator<LocalDateTime> earliestDate = (p, a) -> a.isBefore(p) ? a : p;


         Map<Status,LocalDateTime> latest = history.stream()
                    .filter(isNewOrOpen.negate())
                    .collect(toMap(History::getStatus,
                            History::getChangedtetme,
                            latestDate));

        Map<Status,LocalDateTime> earliest = history.stream()
                    .filter(isNewOrOpen)
                    .collect(toMap(History::getStatus,
                            History::getChangedtetme,
                            earliestDate));

            latest.putAll(earliest);
Tagir Valeev

If I understand your problem correctly, isNewOrOpen predicate uses History.getStatus() and you want to select the history items with earliest date for new/open status and with latest date for other statuses. It's better to define the Comparator which implements this logic (it's supposed that h1 and h2 have the same status here):

Comparator<History> comparator = (h1, h2) -> isNewOrOpen.test(h1) ? 
    h2.getChangedtetme().compareTo(h1.getChangedtetme()):
    h1.getChangedtetme().compareTo(h2.getChangedtetme());

Using this comparator, it's quite easy to define the collector to solve your task:

Collector<History, ?, Map<Status, LocalDateTime>> collector
        = groupingBy(History::getStatus, 
                collectingAndThen(maxBy(comparator), 
                opt -> opt.get().getChangedtetme()));

Note the collectingAndThen usage: maxBy returns Optional<History> and we want to extract the getChangedtetme() (whatever it means).

So finally you can use this collector directly:

Map<Status, LocalDateTime> result = history.stream().collect(collector);

The latestDate and earliestDate seem to be unnecessary.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Merging two Map<String, Integer> with Java 8 Stream API

From Dev

Java 8 Stream API - Select the lowest key after group by

From Dev

Use Java 8 Stream API to filter objects based on an ID and Date

From Dev

Grouping By in java 8 Stream API

From Dev

Grouping By in java 8 Stream API

From Dev

Java 8: Merging two Lists containing objects by key

From Dev

Java 8, stream with another List Index based on

From Dev

Java 8 Stream Filer based on Object property

From Dev

Java 8 Stream indexOf method based on predicate

From Dev

Java 8 Applying stream filter based on a condition

From Dev

Merging arrays based on a value of the key

From Dev

Merging arrays based on a value of the key

From Java

Grouping by ranges with Java 8 Stream API

From Java

Java 8 stream API orElse usage

From Dev

Java 8: merge lists with stream API

From Dev

Is there an aggregateBy method in the stream Java 8 api?

From Dev

Java 8 Stream API equivalent of nested for loops

From Dev

Java 8 Stream API : Filter on instance, and cast

From Dev

Java 8 Stream API Collector Issue

From Dev

Finding enum value with Java 8 Stream API

From Dev

Nested for loops to Java 8 Stream API representation

From Dev

Java 8 Stream API in Android N

From Dev

Java 8 Stream API toMap converting to TreeMap

From Dev

Java 8 stream api control output

From Dev

Java 8 stream API orElse usage

From Dev

Checking list of enums with Java 8 Stream API

From Dev

Multiple aggregate functions in Java 8 Stream API

From Dev

Reducing Map by using Java 8 Stream API

From Dev

Java 8 Stream API Collector Issue