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 Jobs:
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-Tasks 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