如何使用 java 流打印嵌套列表,其中对象包含对自身的引用列表
How to print a nested list using java stream where the Object holds a list of references to itself
我有一个类似于下图的对象:
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 循环。
嗯,使用 Stream
你可以从这里开始:
objs.stream().
map(Obj::getObjId).
forEachOrdered(System.out::println);
并稍作改进:
List<String> collect = objs.stream()
.filter(Objects::nonNull) // Filter only nonNull objects. Avoid NullPointerException
.map(Obj::getObjId)
.peek(System.out::println) // Print the ObjId value from Obj
.collect(Collectors.toList()); // Return the result to a List, if you need.
现在您掌握了从 children 获取值的基本方法。了解一点 Stream
并改进代码示例 ;)
一些不错的链接:
希望对您有所帮助!
你应该使用递归。使用流进行此操作的一种可能方法如下:
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
实例形成一个图),这个解决方案将不起作用,你'我会得到一个巨大的 WhosebugError
.
如果您不能修改 Obj
class,您可以使用接收 Obj
实例的辅助方法实现相同的效果,即在 ObjService
class:
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(", "));
}
我有一个类似于下图的对象:
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 循环。
嗯,使用 Stream
你可以从这里开始:
objs.stream().
map(Obj::getObjId).
forEachOrdered(System.out::println);
并稍作改进:
List<String> collect = objs.stream()
.filter(Objects::nonNull) // Filter only nonNull objects. Avoid NullPointerException
.map(Obj::getObjId)
.peek(System.out::println) // Print the ObjId value from Obj
.collect(Collectors.toList()); // Return the result to a List, if you need.
现在您掌握了从 children 获取值的基本方法。了解一点 Stream
并改进代码示例 ;)
一些不错的链接:
希望对您有所帮助!
你应该使用递归。使用流进行此操作的一种可能方法如下:
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
实例形成一个图),这个解决方案将不起作用,你'我会得到一个巨大的 WhosebugError
.
如果您不能修改 Obj
class,您可以使用接收 Obj
实例的辅助方法实现相同的效果,即在 ObjService
class:
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(", "));
}