简体   繁体   中英

Java 8 Stream Collectors for Maps, misleading groupingBy error

I'm pretty confused by the differences in these two methods, but I'm sure I'm doing something wrong.

I have a working example, and a non-working example below. In the working example, I'm assigning the variable tester as a "Map", In the non-working example I'm trying to assign it to Map. In the second example, the error is shown here:

截图

I am failing to see the connection between the types for the tester variable, and the type of the myMap variable.

//Working Example (or at least it compiles)
public String execute(Map<String, String>  hostProps) {
        Map tester = usages.stream()
            .map(usage -> prepareUsageForOutput(usage, rateCard.get()))
            .collect(Collectors.groupingBy(myMap -> myMap.get("meterName")));    // This case compiles
}

//Compiler Error, just by adding the Map types on line 13, it breaks line 18
public String execute(Map<String, String>  hostProps) {
        Map<String, Object> tester = usages.stream()
            .map(usage -> prepareUsageForOutput(usage, rateCard.get()))
            .collect(Collectors.groupingBy(myMap -> myMap.get("meterName")));   // In this case, the .get() method call can't resolve .get. It doesn't recognize that myMap is a Map. 
}


//This is the method that gets called in the above methods
static Map<String, Object> prepareUsageForOutput(Usage usage, RateCard rateCard ){

}

Update 1 - Wrong Collector Method

While Eran posted the explanation of my original issue, it revealed that I should have been using Collectors.toMap instead of Collectors.groupBy, because my goal was to return a map entry for each map returned from "prepare", where the key was a string, and the value was the map returned from "prepare". groupBy will always return a list of results as the map value.

I also removed the filter statements, as they were irrelevant and significantly complicated the example.

This was the final result that met my goal:

Map<String, Object> tester = usages.stream()
     .map(usage -> prepareUsageForOutput(usage, rateCard.get()))
     .collect(Collectors.toMap(myMap ->(String)myMap.get("meterName"), Function.identity()));

Since prepareUsageForOutput returns a Map<String, Object> , this means the Collectors.groupingBy() collector operates on a Stream<Map<String, Object>> , which means it creates a Map<Object,List<Map<String, Object>>> , not a Map<String, Object> .

This answer doesn't explain the error your compiler gave, but several times I encountered misleading compilation errors where Stream s are involved, so I suggest changing the output type to Map<Object,List<Map<String, Object>>> and see if the error goes away.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM