Java 8流经多个层并连接最底层的所有项目

pik*_*ike 3 java java-8 java-stream

我目前有一个多层结构数据,如下所示:

行业类有一个Set<Company>可以为null 的私有字段.

公司类有一个Set<Division>可以为null 的私有字段.

Division类有一个Set<Group>可以为null 的私有字段.

组类有一个私有字段groupName,可以为null,可以使用getter(getGroupName())检索.

我试图将Industry的一个实例流式传输到Group层,并将所有groupName连接成一个String,其间带有"/".

如果此Industry实例不包含任何groupName,则返回字符串"null".

根据我对Java 8的有限知识,我想这样编码:

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("/")));
Run Code Online (Sandbox Code Playgroud)

这段代码似乎有些瑕疵.另外,我不知道在哪里添加声明,如果Industry无法检索任何groupName,而不是将所有groupName连接成一个字符串,只需返回一个字符串"null".

在我的情况下使用Java 8流的正确方法是什么?

谢谢.

Hol*_*ger 5

Collectors.joining(…)是基于班级StringJoiner.它提供了分隔符,前缀和后缀功能,但遗憾的是无法提供空值.

要添加该功能,我们必须重新实现Collectors.joining,幸运的是,使用时并不那么难StringJoiner.

更改流操作的最后一行

.collect(Collectors.joining("/"));
Run Code Online (Sandbox Code Playgroud)

.filter(Objects::nonNull) // elide all null elements
.collect(()->new StringJoiner("/", "", "").setEmptyValue("null"), // use "null" when empty
         StringJoiner::add, StringJoiner::merge).toString();
Run Code Online (Sandbox Code Playgroud)