Вы должны использовать рекурсию.Один из возможных способов сделать это с потоками заключается в следующем:
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(", "));
}