Briefly: collect(groupingBy())
returns a map Map<K, List<T>>
. How can I replace , for each K
, the value List<T>
by a new value (of class U
) which is computed based on List<T>
, and return Map<K, U>
in the same stream()
?
An example: Suppose I have a Task
, which consists of a taskId
and a list of Job
s:
public class Task { int taskId; List<Job> jobList; }
For each Job
, method getAgentId
determines an "agent" who is able to process it:
// in class Job
int getAgentId() { // return the "agent" who is responsible for @param job }
A Task
is partitioned into multiple sub-Task
s such that each of them can be processed by a separate "agent":
// in class Partition; `Integer` for "agent" id
Map<Integer, Task> partition(Task task) { }
My attempt: I used groupingBy
:
Map<Integer, Task> partition(Task task) {
int id = task.getTaskId();
Map<Integer, List<Job>> agentJobsMap =
task.getJobList().stream()
.collect(groupingBy(Job::getAgentId),
// question here);
}
Question: However I want to return Map<Integer, Task>
instead of Map<Integer, List<Job>>
; that is, I want to wrap the resulting List<Job>
of groupingBy
into a new Task
by new Task(id, the resulting List<Job>)
. How to do that? Or are there alternatives without groupingBy
?
Use the overload of groupingBy
that accepts another Collector
to use on the results:
task.getJobList().stream()
.collect(
groupingBy(
Job::getAgentId,
collectingAndThen(toList(), jobs -> new Task(id, jobs))));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With