I have been playing with BiFunction
(java.util.function
). I ran some examples and and I have one question.
Is there a limitation on how many times the operation can be nested with BiFunction? Is it as simple as nesting a hypothetical
add(a, b)
method as many times as one wants?
e.g. three nested theFunction.apply()
public static int methodContainingMethod
(int a, int b, int c, BiFunction<Integer, Integer, Integer> theFunction) {
return theFunction.apply(theFunction.apply(theFunction.apply(a,b),c),c),c);
}
four nested theFunction.apply()
return
theFunction.apply(theFunction.apply(theFunction.apply(theFunction.apply(a,b),c),c),c),c);
on and on... The number of nesting can go up and on, I tested with nesting the function for over ten times.
I don't have exact requirement as to how many nesting is needed... but I am curious as to how many nesting of such can be done?
First of all, that’s not specific to BiFunction
in any way. So you are basically asking, how deep you can nest method invocations and the simple answer is that the Java programming language does not specify a limitation per se.
There are technical limitations which may restrict the number but these are, well, technical limitations, not limitation by specification. They might be lifted when the technology evolves without changes in the specification.
As Alain O'Dea has explained, a method’s code size is limited to 65535 bytes or to 65534 bytes if the last instruction ought to be covered by an exception handler. The amount of nested method calls supported by this code size depends on some factors. E.g., you are using an interface
and interface method invocation use more bytes than concrete class method invocations (invokevirtual instructions), further, you are using BiFunction<Integer, Integer, Integer>
rather than the straight-forward IntBinaryOperator
so every invocation involves boxing of the int
values which requires additional code.
But there is another technical limitation anyway, the compiler implementation. When trying to compile your example with a higher nesting count, javac
ran from the command line terminated with a stackoverflow at 1500 nested invocation, while Netbeans (using the same compiler code as javac
) managed to compile 2000 nested invocations before the IDE started to exhibit strange behavior (I guess, it doesn’t handle stack overflows of the compiler/ syntax highlighter very well).
That suggests that the IDE had a higher stack size or other differences in the environmental setup affected the initial stack depth before the expression got parsed. This leads to the conclusion that there is no hard limit in practice. You may be able to write code which one compiler manages to compile without problems whereas another one bails out— not a good idea to max this out.
After all, the equivalent of your question’s code could be written as:
public static int methodContainingMethod(
int a, int b, int c, BiFunction<Integer, Integer, Integer> theFunction) {
int value = theFunction.apply(a, b);
for(int i=0; i<asDeepAsYouWannaGo; i++)
value=theFunction.apply(value, c);
return value;
}
though I think, what you have in mind, is more like:
public static int methodContainingMethod(
IntBinaryOperator theFunction, int first, int second, int... rest) {
int value = theFunction.applyAsInt(first, second);
for(int next: rest) value=theFunction.applyAsInt(value, next);
return value;
}
or
public static OptionalInt methodContainingMethod(
IntBinaryOperator theFunction, int... arguments) {
return IntStream.of(arguments).reduce(theFunction);
}
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