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

标签 java java-8 java-stream

我目前有一个像这样的多层结构数据:

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()).

我试图将 Industry 的一个实例一直向下传输到组层,并将所有组名连接成一个字符串,中间使用“/”。

如果 Industry 的 this 实例不包含任何 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("/")));

这段代码似乎在某些方面存在缺陷。此外,我不确定在哪里添加以下语句:如果 Industry 无法检索任何 groupName,而不是将所有 groupName 连接成一个字符串,只需返回一个字符串“null”。

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

谢谢。

最佳答案

Collectors.joining(…) 基于类 StringJoiner。它提供其定界符、前缀和后缀功能,但遗憾的是不能提供空值。

要添加该功能,我们必须重新实现 Collectors.joining,幸好在使用 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 流经多个层并连接最底层的所有项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46101593/

相关文章:

Java 8 javax.net.ssl.SSLPeerUnverifiedException : peer not authenticated, 但不是 Java 7

java - 忽略 Git 中的 .classpath 和 .project

java - JDK8编译速度慢

java - 在 Eclipse 中混淆代码?

java - '->' 在 Java 中有什么作用?

java - Java 流中的中间操作

java - 我可以检查 Java 8 流是否至少包含 n 个元素

java - 获取得分为 "x"分的学生列表 Java8 List<Student> 到 Map<Marks,List<Name>>,限制名称数量

java - 如何在 JSON 文件的不同数组和对象中导航

java - 验证上传到服务器的文件