What's the difference between groupingby and mapping in Collectors (Java)?

若如初见. 提交于 2021-02-06 08:43:34

问题


Take a look at this piece of code.

// group by price, uses 'mapping' to convert List<Item> to Set<String>
    Map<BigDecimal, Set<String>> result =
            items.stream().collect(
                    Collectors.groupingBy(Item::getPrice,
                            Collectors.mapping(Item::getName, Collectors.toSet())
                    )
            );

Is groupingBy and Mapping interchangeable? What is their differences?

For the third parameter in collect(), would I get the same output type Map if I used Collectors.toList() instead of Collectors.toSet()? I heard that toList() is a more popular option.


回答1:


Is groupingBy and Mapping interchangeable?

No, they are completely different. groupingBy lets you create a Map where the key is the first argument passed to groupingBy and the value is a List of the element type of the Stream.

Collectors.groupingBy(Item::getPrice) would generate a Map<BigDecimal, List<Item>> (assuming Item::getPrice returns a BigDecimal. Passing the mapping Collector as an argument to Collectors.groupingBy() allows you to change the value of the output map (in your example, you change it to Set<String>).

For the third parameter in collect(), would I get the same output type Map if I used Collectors.toList() instead of Collectors.toSet()?

No, you would get a Map<BigDecimal, List<String>>.




回答2:


No, the two are completely different.

Collectors.groupingBy takes a function which creates keys and returns a collector which returns a map from keys to collections of objects in the stream which have that same key.

Collectors.mapping, on the other hand, takes a function and another collector, and creates a new collector which first applies the function and then collects the mapped elements using the given collectors. Thus, the following are equivalent:

items.stream().map(f).collect(c);
items.stream().collect(Collectors.mapping(f, c));

Collectors.mapping is most useful in situations where you do not have a stream, but you need to pass a collector directly. An example of such a situation is when using Collectors.groupingBy.

items.stream().collect(Collectors.groupingBy(Item::getPrice, Collectors.toSet()))

yields a Map<BigDecimal,Set<Item>> (assuming getPrice() returns a BigDecimal). However,

items.stream().collect(Collectors.groupingBy(Item::getPrice,
    Collectors.mapping(Item::getName, Collectors.toSet())))

returns a Map<BigDecimal,Set<String>>. Before collecting the items, it first applies Item.getName to them.



来源:https://stackoverflow.com/questions/40826431/whats-the-difference-between-groupingby-and-mapping-in-collectors-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!