As I posted in the comment this basically is a well know function "fold" from functional programming.
What is fold? It's called fold because it "folds" a given data structure using some base value and some function. In your case the data structure to be folded is the Queue. The base value is the first argument of foldIt (u), the bidi function is the function that will tell you how to fold it. It's generalized using 3 types because it takes in 2 types and computes a result of the 3rd type.
Ok, what? Very basic example of folding would be:
u = 1;
queue = (2,3,4)
bidi(t,u) = return (t+u)
Here first foldIt(u, queue, bidi) would add 1+2=3 and then call foldIt(3,(3,4),bidi). So as you can see the base value of the next step is the result of the previous step's bidi. It goes on till there are elements to be folded and returns the accumulated (folded) value.
The problem: Now the problem here is that someone tried to implement it in a functional fashion on the JVM which does not fully support functional style programming (even in Java8). Well ok the JVM does support it (for instance Scala does it), but Java does not support it (for reasons which aren't necessarily good).
Because the return statement is a call to the foldIt() method and nothing more this is called a tail recursion. Tail recursions are nice because you do not need a new stack frame for each new call, you can reuse the current stack frame as there are no local variables that have to be persisted during the recursion.
Unfortunately Java does not support tail-call optimization and it will create a new stack frame for each invocation of foldIt().
The solution to this problem was already posted by @Tassos Bassoukos and you simply need to replace the recursive invocation to foldIt() with an iteration. How is it done usually? Well basically what the computer does when you use recursion (or any method invocation) is it creates a new stack frame for each invocation that holds information about it (local variables, some pointers etc.) and push it to the current stack of execution. So to overcome this you can make an iteration and push needed values onto your own stack, that might save you some space (you dont need to store pointers required by the computer to know to where in the memory it needs to go back from the recursive call etc.). In this case (tail recursion) it's even better because you have no local variables and you can skip the stack! Something like this:
public class CommonFolder<T, U> implements FolderMaster<T, U>{
public U foldIt(U u, Queue<T> ts, FunctionBi<T, U, U> bidi){
if(u == null || ts == null || bidi == null)
throw new IllegalArgumentException();
while (!ts.isEmpty()) {
u = bidi.applyIt(ts.poll(), u);
}
return u;
}
}
Here you are not invoking anything recursively so you won't have too many new stack frames (well only a constant amount for isEmpty() and applyIt()) and no stackoverflow.