I currently have a multiple layer structure data that is like this:
Industry class has a private field
Set<Company>
that can be null.Company class has a private field
Set<Division>
that can be null.Division class has a private field
Set<Group>
that can be null.Group class has a private field
groupName
that can be null and is retrievable with a getter (getGroupName()
).
I am trying to stream an instance of Industry all way down to the Group layer and concatenate all the groupName's into one String with "/" in between.
If the this instance of Industry doesn't contain any groupName, return the string "null".
Based on my limited knowledge of Java 8, I am thinking of coding like this:
industry.stream()
.flatmap(industry -> industry.getCompanies().stream())
.filter(Objects::nonNull)
.flatmap(company -> company.getDivisions().stream())
.filter(Objects::nonNull)
.flatmap(division -> division.getGroups().stream())
.map(group -> group.getGroupName)
.collect(Collectors.joining("/")));
This code seems to flawed in someway. Also, I am not sure where to add the statement that if Industry cannot retrieve any groupName, rather than concatenate all groupName into one string simply return a string "null".
What is the proper way to use Java 8 stream in my situation?
Thanks.
Collectors.joining(…)
is based on the class StringJoiner
. It offers its delimiter, prefix, and suffix features, but unfortunately not the ability to provide the empty value.
To add that feature, we’ll have to re-implement Collectors.joining
, which thankfully is not so hard when using StringJoiner
.
Change the last line of your stream operation
.collect(Collectors.joining("/"));
to
.filter(Objects::nonNull) // elide all null elements
.collect(()->new StringJoiner("/", "", "").setEmptyValue("null"), // use "null" when empty
StringJoiner::add, StringJoiner::merge).toString();
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