Weeedooo
Weeedooo

Reputation: 557

Stream().map() result as Collectors.toMap() value

I'm having List<InstanceWrapper>, for each element I want to do some logic that will result in some String message. Then, I want to take create Map<String, String>, where key is InstanceWrapper:ID and value is message;

private String handle(InstanceWrapper instance, String status) {
    return "logic result...";
}

private Map<String, String> handleInstances(List<InstanceWrapper> instances, String status) {
    return instances.stream().map(instance -> handle(instance, status))
                    .collect(Collectors.toMap(InstanceWrapper::getID, msg -> msg));     
}

But it wont compile, I'm getting, how do I put stream().map() result into collectors.toMap() value?

The method collect(Collector<? super String,A,R>) in the type Stream<String> is not applicable for the arguments (Collector<InstanceWrapper,capture#5-of ?,Map<String,Object>>)

Upvotes: 1

Views: 1527

Answers (2)

Andronicus
Andronicus

Reputation: 26056

You cannot map before collecting to map, because then you're getting Stream of Strings and loosing information about InstanceWrapper. Stream#toMap takes two lambdas - one generating keys and second - generating values. It should be like that:

instances.stream()
    .collect(Collectors.toMap(InstanceWrapper::getID, instance -> handle(instance, status));

The first lambda generates keys: InstanceWrapper::getID, the second one - associated values: instance -> handle(instance, status).

Upvotes: 5

Smutje
Smutje

Reputation: 18163

You map every InstanceWrapper to a String but if you want to use the InstanceWrapper later to extract its ID you can not do this. Try something like this instead:

return instances.stream()
    .collect(Collectors.toMap(InstanceWrapper::getID, (InstanceWrapper instanceWrapper) -> this.handle(instanceWrapper, status)));     

Edit:

To beautify this, you could simulate currying a little bit like this:

private Function<InstanceWrapper, String> handle(String status) {
    return (InstanceWrapper instanceWrapper) -> "logic result...";
}

private Map<String, String> handleInstances(List<InstanceWrapper> instances, String status) {
    return instances.stream()
        .collect(Collectors.toMap(InstanceWrapper::getID, this.handle(status)));     
}

Upvotes: 3

Related Questions