Multilevel grouping

Earlier, we mentioned that two of three flavors of groupingBy() take another collector as an argument. Moreover, we said that this can be any collector. By any collector, we mean groupingBy() as well.

By passing groupingBy() to groupingBy(), we can achieve n-levels of grouping or multilevel grouping. Mainly, we have n-levels of classification functions.

Let's consider the following list of Melon:

List<Melon> melonsSugar = Arrays.asList(
new Melon("Crenshaw", 1200, HIGH),
new Melon("Gac", 3000, LOW), new Melon("Hemi", 2600, HIGH),
new Melon("Hemi", 1600), new Melon("Gac", 1200, LOW),
new Melon("Cantaloupe", 2600, MEDIUM),
new Melon("Cantaloupe", 3600, MEDIUM),
new Melon("Apollo", 2600, MEDIUM), new Melon("Horned", 1200, HIGH),
new Melon("Gac", 3000, LOW), new Melon("Hemi", 2600, HIGH));

So, each Melon has a type, a weight, and an indicator of sugar level. First, we want to group melons by the sugar indicator (LOW, MEDIUM, HIGH, or UNKNOWN (default)). Furthermore, we want to group melons by weight. This can be accomplished via two levels of grouping, as follows:

Map<Sugar, Map<Integer, Set<String>>> bySugarAndWeight = melonsSugar.stream()
.collect(groupingBy(Melon::getSugar,
groupingBy(Melon::getWeight, TreeMap::new,
mapping(Melon::getType, toSet()))));

The output is as follows:

{
MEDIUM = {
2600 = [Apollo, Cantaloupe], 3600 = [Cantaloupe]
},
HIGH = {
1200 = [Crenshaw, Horned], 2600 = [Hemi]
},
UNKNOWN = {
1600 = [Hemi]
},
LOW = {
1200 = [Gac], 3000 = [Gac]
}
}

We can now say that Crenshaw and Horned weigh 1,200 g and have a high percentage of sugar. We also have Hemi at 2,600 g with a high percentage of sugar.

We can even represent our data in a table, as shown in the following diagram:

Now, let's learn about partitioning.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset