问题描述
我目前有一个多层结构数据,如下所示:
I currently have a multiple layer structure data that is like this:
公司类有私有字段设置< Division>
可以为null。
Company class has a private field Set<Division>
that can be null.
分类有一个私有字段设置< Group>
可以是null。
Division class has a private field Set<Group>
that can be null.
组类有一个私有字段 groupName
,可以为null,并且是
可以使用getter( getGroupName()
)。
Group class has a private field groupName
that can be null and is retrievable with a getter (getGroupName()
).
我正在尝试流式传输实例行业一直到Group层,并将所有groupName连接成一个String,中间带有/。
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.
如果此行业实例不包含任何groupName,返回字符串null。
If the this instance of Industry doesn't contain any groupName, return the string "null".
基于我对Java 8的有限知识,我想这样编码:
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("/")));
此代码似乎有些瑕疵。另外,我不知道在哪里添加声明,如果Industry无法检索任何groupName,而不是将所有groupName连接成一个字符串,只需返回一个字符串null。
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".
在我的情况下使用Java 8流的正确方法是什么?
What is the proper way to use Java 8 stream in my situation?
谢谢。
推荐答案
Collectors.joining(...)
基于类 StringJoiner
。它提供了分隔符,前缀和后缀功能,但遗憾的是无法提供空值。
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.
要添加该功能,我们必须重新实现 Collectors.joining
,幸运的是,使用 StringJoiner
时并不是那么难。
To add that feature, we’ll have to re-implement Collectors.joining
, which thankfully is not so hard when using StringJoiner
.
更改流操作的最后一行
.collect(Collectors.joining("/"));
到
.filter(Objects::nonNull) // elide all null elements
.collect(()->new StringJoiner("/", "", "").setEmptyValue("null"), // use "null" when empty
StringJoiner::add, StringJoiner::merge).toString();
这篇关于Java 8流经多个层并连接最底层的所有项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!