Divide A List To Sub-Lists Via Collectors
- by Joe Jr Yamut
Consider a List of Color objects with attributes of index, name and group. This object is defined as,
public class Color {
private int index;
private String name;
private Group group;
}
Group is simply an Enum of,
public enum Group {
RED,
GREEN,
BLUE;
}
My list of colors are the following,
Color royalBlue = new Color(7, "Royal Blue", Group.BLUE);
Color soulRedCrystal = new Color(2, "Soul Red Crystal", Group.RED);
Color matchaGreen = new Color(4, "Matcha Green", Group.GREEN);
Color deepOcean = new Color(5, "Deep Ocean", Group.BLUE);
Color darkPine = new Color(3, "Dark Pine", Group.GREEN);
Color sexyRouge = new Color(1, "Sexy Rouge", Group.RED);
Color hyperlinkBlue = new Color(6, "Hyperlink Blue", Group.BLUE);
List<Color> colorList = new ArrayList<>();
// add colors above after
Now, I want to divide these colors into their own sub-lists of color grouping based on the value of the object’s Group attribute.
Traditionally, this can be done with the venerable for loop and some if-else statements.
List<Color> redGroup = new ArrayList<>();
List<Color> greenGroup = new ArrayList<>();
List<Color> blueGroup = new ArrayList<>();
for (Color color : colorList) {
if (color.getGroup().equals(Group.BLUE) {
// assign to its own group of blues
blueGroup.add(color);
}
// Other code omitted for brevity
}
If I want to not write it with a bunch of if-else statements, the Java 8 Stream API approach can be utilized. For multiple groups, one way is to use Collectors.groupingBy to separate the elements each to their respective group.
Map<Group, List<Color>> colorGroups = colorList.stream()
.collect(Collectors.groupingBy(color -> color.getGroup()));
Each color group can then be retrieved (and assigned to a sub-list as necessary) like this,
colorGroups.get(Group.BLUE));
Both ways will have the same output, regardless.
[Color(index=2, name=Soul Red Crystal, group=RED), Color(index=1, name=Sexy Rouge, group=RED)]
[Color(index=4, name=Matcha Green, group=GREEN), Color(index=3, name=Dark Pine, group=GREEN)]
[Color(index=7, name=Royal Blue, group=BLUE), Color(index=5, name=Deep Ocean, group=BLUE), Color(index=6, name=Hyperlink Blue, group=BLUE)]
Or if I want to group these colors according to their index attribute and split them out into evens and odds, use the Collectors.partitioningBy approach.
Map<Boolean, List<Color>> colorGroups = colorList.stream()
.collect(Collectors.partitioningBy(color -> color.getIndex() % 2 == 0));
In order to get the even group,
colorGroups.get(true)
Here, true has the colors that have even-numbered index because of our condition – color.getIndex() % 2 == 0. The odd-numbered colors will then be assigned to false.
[Color(index=2, name=Soul Red Crystal, group=RED), Color(index=4, name=Matcha Green, group=GREEN), Color(index=6, name=Hyperlink Blue, group=BLUE)]
[Color(index=7, name=Royal Blue, group=BLUE), Color(index=5, name=Deep Ocean, group=BLUE), Color(index=3, name=Dark Pine, group=GREEN), Color(index=1, name=Sexy Rouge, group=RED)]
Similar Posts:
- > Rewriting Nested Ifs With Java 8 Stream July 19, 2021
- > that annoying blue backround on RH9 January 27, 2007
- > NPE-safe String Comparisons, And More… March 6, 2023
- > Removing Null Values In A List Using Java 8 Stream October 22, 2020
- > Firefox 7 Finally Hits Ubuntu 11.04 October 6, 2011
Consider a List of Color objects with attributes of index, name and group. This object is defined as, Group is simply an Enum of, My list of colors are the following, Now, I want to divide these colors into their own sub-lists of color grouping based on the value of the object’s Group attribute. Traditionally,…