Как рекурсия работает с Java 8 Stream?

У меня есть такой метод, где я использую рекурсию с потоками:

  private static List<Member> convertToFlatList(List<Member> memberList)
  {
    return memberList.stream().flatMap(i -> Stream.concat(Stream.of(i), convertToFlatList(i.getChildren()).stream())).collect(Collectors.toList());
  }

Допустим, у класса Member есть дочерний список членов, который всегда инициализируется пустым списком. Здесь я делаю преобразование иерархического списка членов в плоский список. Я понимаю эту часть. Я не понимаю, как здесь работает рекурсия.

В рекурсии он прекращается, когда выполняются определенные условия. Но здесь я не даю никаких условий для прекращения намеренно. Так как же здесь работает завершающая часть?

Ответ 1

Рекурсия заканчивается, когда memberList будет пустым, так как в этом случае будет возвращен пустой List.

т.е. когда i.getChildren() является пустым List, рекурсивный вызов convertToFlatList(i.getChildren()) получит пустой List, поэтому конвейер Stream не будет делать другой рекурсивный вызов (так как у него нет элементов для выполнения flatMap в ) и вернет пустой List.

Ответ 2

Прекращение происходит потому, что для "листьев", которые не имеют детей,

Stream.concat(Stream.of(i), convertToFlatList(i.getChildren()).stream())

вызовет convertToFlatList для пустого списка, а применение flatMap() для пустого потока не вызовет операцию отображения.