I have an object which looks similar to what's shown below:
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 + "]";
  }
}
How can I print the list of objId using streams?
EDIT
Obj can contain a list of Obj and it's children can contain a list of obj objects. If the depth is 5 levels, is it possible to print all the objId values from the top most obj to the values of the child at 5th level. I want to avoid nested for loops.  
You should use recursion. One possible way to do it with streams is as follows:
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(", "));
}
Note that this works well as long as your Obj instances are arranged in a tree-like structure. If you have a specific Obj instance that is both a parent at some level and a child in some lower level (i.e. if your Obj instances form a graph), this solution won't work and you'll get a huge StackOverflowError.
If you can't modify the Obj class, you could achieve the same with helper methods that receive an instance of Obj i.e. in a 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(", "));
}
                        Well, using Stream you can start from here:
objs.stream().
            map(Obj::getObjId).
            forEachOrdered(System.out::println);
And improving a little bit:
    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.
Now you have the basic way to get values from children. Learn a little about Stream and improve the code example ;)
Some nice links:
Hope this helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With