Hi Junilu!
Personally, I see recursion only as an appropriate tool for a few use-cases, as often it's not easy to wrap your head around more complex examples.
And the lack of tail-call optimization introduces another factor against it for bigger data structures.
In the recursion chapter, I mention the lack of TCO and the problem of StackOverflowErrors that might follow.
I didn't find a "nice" way around it and link to the book's code repository, where I talk about using a Stream with a custom type that works like a recursive call but with a constant stack depth.
However, it's more of a proof of concept than an actual suggestion
you should use in your code.
https://github.com/benweidig/a-functional-approach-to-java/blob/main/part-2/12-recursion/other/stream-recursion.md
Project Loom will introduce stack unwinding, which hopefully improves the situation for recursion and TCO in Java.