java - 如何使用 java 流打印嵌套列表,其中对象包含对自身的引用列表

标签 java java-8 java-stream tostring

我有一个类似于下图的对象:

public class Obj {
  private List<Obj> objs;
  private String objId;

  public List<Obj> getObjs() {
    return objs;
  }

  public String getobjId() {
    return objId;
  }

  @Override
  public String toString() {
    return "Obj [objs=" + objs + ", objId=" + objId + "]";
  }

}

如何使用流打印 objId 的列表?

编辑

Obj 可以包含一个 Obj 列表,它的子元素可以包含一个 obj 对象列表。如果深度为 5 级,是否可以打印从最顶层 obj 到第 5 级子级的值的所有 objId 值。我想避免嵌套的 for 循环。

最佳答案

你应该使用递归。使用流进行此操作的一种可能方法如下:

private Stream<Obj> allObjs() {
    return Stream.concat(
        Stream.of(this), 
        objs == null ? Stream.empty() : objs.stream().flatMap(Obj::allObjs));
}

@Override
public String toString() {
    return allObjs()
        .map(Obj::getobjId)
        .collect(Collectors.joining(", "));
}

请注意,只要您的 Obj 实例以树状结构排列,此方法就可以正常工作。如果您有一个特定的 Obj 实例,它既是某个级别的父实例,又是某个较低级别的子实例(即,如果您的 Obj 实例形成一个图),则此解决方案获胜不工作,你会得到一个巨大的 StackOverflowError


如果您不能修改 Obj 类,您可以使用接收 Obj 实例的辅助方法实现相同的效果,即在 ObjService类:

public static Stream<Obj> allObjs(Obj o) {
    if (o == null) return Stream.empty(); // in case the argument is null
    return Stream.concat(
            Stream.of(o), 
            o.getObjs() == null ?
                Stream.empty() :
                o.getObjs().stream().flatMap(ObjService::allObjs));
}

public static String deepToString(Obj o) {
    return ObjService.allObjs(o)
        .map(Obj::getobjId)
        .collect(Collectors.joining(", "));
}

关于java - 如何使用 java 流打印嵌套列表,其中对象包含对自身的引用列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52798041/

相关文章:

java - 如何避免 Apache Solr 中的 Java OutOfMemoryMemory Java 堆空间

java - 为什么我看不到 TestNG 抛出的异常?

java - SonarQube 可配置技术债务

java - 使用谷歌应用程序引擎中托管的java程序调用facebook api(php)

java - 如何从员工 map Prop 中检索 id 值

lambda - 使用 JDK8 和 lambda 压缩流 (java.util.stream.Streams.zip)

java - 函数 Completable Future 上的 gradle 不兼容错误

java - 如何在 Java 8 中将 continue 放入 forEach 循环中

Java - 使用多个完成阶段来形成一个响应 json

java - 如何计算 Java 8 中嵌套类结构中属性的总和?