Существуют средства глубокой рекурсии (с риском взорвать стек), если аргумент метода не может быть сразу разрешен. То есть конечный результат вызванного метода зависит от результата самого метода. Псевдо:
Result process(Parent parent) {
Result result = new Result();
for (Child child : parent.getChildren()) {
result.update(process(child));
}
return result;
}
Это заставляет код ждать с update()
, пока результат не станет известен, и, следовательно, он останется в стеке. И он накапливается при каждом вызове метода.
Вы можете оптимизировать его для использования хвостовой рекурсии вместо этого с изменяемым объектом результата в качестве аргумента:
void process(Parent parent, Result result) {
for (Child child : parent.getChildren()) {
result.update(child);
process(child, result);
}
}
Таким образом, update()
может быть выполнен немедленно, так как аргумент сразу разрешается. Если после вызова process()
не существует возвращаемого значения или какой-либо другой логики, среда выполнения может оптимизировать его, отбрасывая вызов из стека. Также смотрите вышеупомянутую статью вики о хвостовой рекурсии и этот сайт .
Однако .. Код, который вы разместили, кажется, уже хвост рекурсивным. Так что проблема кроется где-то еще. После изучения вашего кода, похоже, вы каждый раз перебираете одинаковых детей. То есть есть просто средство бесконечного цикла. Вероятно, проверка if
является фиктивной, и / или дочерние элементы имеют обратные ссылки в своем собственном родительско-дочернем дереве.