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.
The groupingBy() method of Collectors class in Java are used for grouping objects by some property and storing results in a Map instance.
The toList() method of Collectors Class is a static (class) method. It returns a Collector Interface that gathers the input data onto a new list. This method never guarantees type, mutability, serializability, or thread-safety of the returned list but for more control toCollection(Supplier) method can be used.
In Java 8, you retrieve the stream from the list and use a Collector to group them in one line of code. It's as simple as passing the grouping condition to the collector and it is complete. By simply modifying the grouping condition, you can create multiple groups.
flatMap , as it can be guessed by its name, is the combination of a map and a flat operation. That means that you first apply a function to your elements, and then flatten it. Stream. map only applies a function to the stream without flattening the stream.
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.
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>>
.
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