Juan Juan - 1 month ago 28
Groovy Question

Java 8 Stream groupingBy from Groovy

I'm trying to use Java 8 Stream API with groovy using @CompileStatic:

Writing the groupingBy is giving me a headache, the error says:

groupingBy in java.util.stream.Collectors cannot be applied to groovy.lang.Closure<java.lang.String>


Currently using Java 8 and Groovy 2.4.7

My intention is:


  1. Use map to build DTOs

  2. Use collect with groupingBy to create a map using the UUIDs as keys



This is the working code (developed using "Will Lp" and "BalRog" support).

import groovy.transform.CompileStatic
import groovy.transform.Immutable

import java.util.function.Function
import static java.util.stream.Collectors.groupingBy;

@CompileStatic
public class ThanksForChecking {

@Immutable
public static class Relation {
String entityUUID
}

public static void main(String[] args) {
List<LinkedHashMap<String, String>> rows = [
[entityUUID: "uuid 1"],
[entityUUID: "uuid 2"]
]

Map<String, List<Relation>> relations = rows.stream()
.map { row -> new Relation(row as HashMap) }
.collect(groupingBy((Function) { Relation r -> return r.entityUUID }))

println(relations);

assert relations == [
"uuid 1": [new Relation(entityUUID: "uuid 1")],
"uuid 2": [new Relation(entityUUID: "uuid 2")]
]
}
}

Answer

You need to explicitly cast the closure to Function, which is the argument type that Collectors.groupBy() expects. Change this line:

    .collect(groupingBy { Relation r -> return r.entityUUID })

To this:

    .collect(groupingBy((Function) { Relation r -> return r.entityUUID }))

(Remember to import java.uti‌​l.function.Function)