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);
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.
Comments