Reputation: 332
I have a list how can I convert it to a Map in which I can have keys with minimum value as key value pair. I want to convert this code to streams.
Map<Long, Date> formToDate = new HashMap<>();
for(FormInstance formInstance : formInstances) {
if(formToDate.get(formInstance.getForm().getId()) == null) {
formToDate.put(formInstance.getForm().getId(), formInstance.getCreatedDate());
}
else{
Date prevDate = formToDate.get(formInstance.getForm().getId());
Date thisDate = formInstance.getCreatedDate();
formToDate.put(formInstance.getForm().getId(), prevDate.before(thisDate) ? prevDate : thisDate);
}
}
to something like this:
Map<Long, List<Date>> formToDate = formInstances.stream()
.collect(
Collectors.groupingBy(formInstance -> formInstance.getForm().getId(),
Collectors.mapping(FormInstance::getCreatedDate, Collectors.toList())));
But instead of returning list all I want to have the smallest date.
Upvotes: 0
Views: 110
Reputation: 393791
Another option is to use Collectors.groupingBy
in combination of Collectors.mapping
and Collectors.minBy
:
Map<Long, Optional<Date>> formToDate =
formInstances.stream()
.collect(Collectors.groupingBy(fi -> fi.getForm().getId(),
Collectors.mapping(FormInstance::getCreatedDate,
Collectors.minBy(Date::compareTo))));
Upvotes: 0
Reputation: 4555
Flown's answer is nice if you really want to use streams, but often it is possible to do without while still taking advantage of newer Java features. I have seen many cases (myself included) in which streams were used for the sake of using streams instead of taking a simpler, more direct approach.
If you already have a list and want to avoid creating a stream, you can use the new Map.merge()
method:
Map<Long, Date> minimum = new HashMap<>();
forms.forEach(form -> minimum.merge(form.getForm().getId(),
form.getCreatedDate(),
(date, date2) -> date.before(date2) ? date : date2));
Aside from merge
, Map
has many methods that can make things like this easier: computeIfAbsent
, getOrDefault
, or even the "old" containsKey
method can make code a lot more readable by replacing common boilerplate snippets, like the one you used:
if (map.get(key) == null) { add } else { test and put }
Upvotes: 0
Reputation: 11740
There is a Collector::toMap
implementation which provides a merge function. This can be used to determine the smallest date from two different entries with same id like:
Map<Long, Date> minimum = formInstances.stream().collect(Collectors.toMap(
fi -> fi.getForm().getId(),
FormInstance::getCreatedDate,
(date, date2) -> date.before(date2) ? date : date2
));
Upvotes: 1