当前位置: 首页 > 知识库问答 >
问题:

Java8流过多层,并在最底层连接所有项目

华欣怡
2023-03-14

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

行业类有一个私有字段

公司类有一个私有字段

Division类有一个私有字段

组类有一个私有字段GroupName,该字段可以为空,并且可以用getter(getGroupName())检索。

我试图将一个工业实例一直流到组层,并将所有组名称连接到一个字符串中,中间有“/”。

如果Industry的this实例不包含任何group Name,则返回字符串"null"。

基于我对Java8有限的了解,我正在考虑这样编码:

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("/")));

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

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

谢谢


共有3个答案

龙逸清
2023-03-14

下面是一个空检查的示例:

String s = industries.stream()
.filter( i -> i.getCompanies() != null ).flatMap( i -> i.getCompanies().stream() )
    .filter( c -> c != null && c.getDivisions() != null ).flatMap( c -> c.getDivisions().stream() )
        .filter( d -> d != null && d.getGroups() != null ).flatMap( d -> d.getGroups().stream() )
            .filter( g -> g != null && g.getGroupName() != null ).map( g -> g.getGroupName() )                    
.collect( Collectors.joining("/") );   

您可以用Holger的示例替换Collectors.joining ("/")

雍焱
2023-03-14

我理解你的问题,因为几乎任何东西都可以是空的。在这种情况下,您可以创建自己的函数来处理这个问题。我做了这样一个:

/**
 * Creates a stream function for the provided collection function which ignores all null values.
 * Will filter out null values passed into the collection function and null values from the resulting stream
 * @param collectionFn
 * @param <T>
 * @param <R>
 * @return
 */
public static <T, R> Function<T, Stream<R>> nullSafeMapper(Function<T, Collection<R>> collectionFn) {
    return (v) -> Optional.ofNullable(v)
            .map(collectionFn)
            .map(Collection::stream)
            .orElse(Stream.empty())
            .filter(Objects::nonNull);
}

基本上它是完全空安全的,过滤掉输入和输出中的任何空值。并且可以这样使用:

industries.stream()
    .flatMap(SO46101593.nullSafeMapper(Industry::getCompanies))
    .flatMap(SO46101593.nullSafeMapper(Company::getDivisions))
    .flatMap(SO46101593.nullSafeMapper(Division::getGroups))
    .map(group -> group.getGroupName())
    .filter(Objects::nonNull) // filter out null group names
    .collect(Collectors.joining("/"));

你也可以把这个逻辑直接推到你的表达式中,但是因为它必须重复3次,所以有点...冗长和重复

张丁雷
2023-03-14
匿名用户

Collectors.joining(...)基于类StringJoiner。它提供了分隔符、前缀和后缀功能,但不幸的是不能提供空值。

要添加该功能,我们必须重新实现收集器。加入,谢天谢地,当使用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();

 类似资料:
  • 问题内容: 我目前有一个这样的多层结构数据: 行业类具有一个私有字段,可以为null。 公司类具有一个私有字段,可以为null。 Division类具有一个私有字段,可以为null。 组类具有一个私有字段,该字段可以为null,并且可以使用getter()检索。 我正在尝试将Industry的一个实例一直向下传输到Group层,并将所有groupName串联到一个字符串中,并且在两者之间使用“ /

  • 所以我知道docker正在使用/var/lib/docker/存储每个容器和图像。。。正当 这意味着我能对我的容器做的唯一优化是优化 /var/lib/docker/坐在上面的底层fs? 在这个意义上,我是否可以假设我应该优化我的底层系统fs的挂载选项?例如ext4 noatime,noadirtime等 另外,我可以使用不同的挂载/var/lib/docker/folder吗??底层磁盘dock

  • 比如有对象 我只能按照顺序拿到数组['a', 'b', 'c', 'd', 'f'] 如果想给f赋值, 只能 如果想要写上面这个表达式的通用函数,要怎么写。

  • LocallyConnected1D层 LocallyConnected2D层

  • 段合并的底层控制 读者应该已经了解每个ElasticSearch索引都由一个或多个分片加上零个或者多个分片副本组成(已经在第一章 介绍ElasticSearch论述过)。而且每个分片和分片副本实际上是Apache Lucene的索引,由多个段(至少一个段)组成。读者应该还记得,段数据都是一次写入,多次读取,当然保存删除文档的文件除外,该文件可以随机改变。经过一段时间,当条件满足时,多个小的段中的内

  • 在本书中我们也遇到了不少底层的命令。 我们遇到的第一个底层命令是在 合并请求引用 中的 ls-remote 命令。我们用它来查看服务端的原始引用。 我们在 手动文件再合并、 Rerere 及 索引 章节中使用 ls-files 来查看暂存区的更原始的样子。 我们同样在 分支引用 一节中提到了 rev-parse 命令,它可以接受任意字符串,并将其转成一个对象的 SHA-1 值。 我们在 Git 内