嵌套BiFunction的深度(或限制)(如果有) [英] What is the depth (or limitation if any) for nesting BiFunction

查看:264
本文介绍了嵌套BiFunction的深度(或限制)(如果有)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在玩 BiFunction java.util.function )。我运行了一些示例,并且我有一个问题。


操作可以嵌套多少次有限制
与BiFunction?是否像嵌套一个假想的 add(a,b)
方法一样简单多少?




例如三个嵌套 theFunction.apply()

  public static int methodContainingMethod 
(int a,int b,int c,BiFunction< Integer,Integer,Integer> theFunction){
返回theFunction.apply(theFunction.apply(theFunction.apply(a,b),c),c) ,C);

四个嵌套 theFunction.apply()
$ p $返回
theFunction.apply(theFunction.apply(theFunction.apply(theFunction.apply(a ,b),C),c)中,c)中,C);




...嵌套的数量可以增加我测试了
嵌套函数十次以上。


我没有确切的要求很多嵌套是需要的......但我很好奇这样的嵌套有多少可以完成? 解决方案

首先,这并不是特定于任何方式的 BiFunction 。所以你基本上都在问,嵌套方法调用有多深,而简单的答案是Java编程语言本身没有指定一个限制。



有技术限制这可能会限制数量,但这些都是技术限制,不受规范的限制。当技术发展而不改变规范时,它们可能会被解除。

正如 Alain O'Dea解释说,如果最后的指令应该由异常处理程序覆盖,则方法的代码大小限制为65535字节或65534字节。此代码大小支持的嵌套方法调用的数量取决于一些因素。例如,您正在使用接口,并且接口方法调用使用的字节数多于具体的类方法调用(invokevirtual指令),此外,您使用的是 BiFunction< Integer,Integer,Integer> ,而不是简单的 IntBinaryOperator ,所以每次调用都会包含 int 值,这需要额外的代码。



但是,编译器的实现还有另一个技术限制。当试图用更高的嵌套计数编译示例时,命令行中的 javac 以1500嵌套调用中的stackoverflow结束,而Netbeans(使用相同的编译器代码 javac )在IDE开始显示奇怪的行为之前设法编译2000嵌套的调用(我猜,它不能很好地处理编译器/语法高亮器的堆栈溢出)。 / p>

这表明在解析表达式之前,IDE具有更高的堆栈大小或环境设置中影响初始堆栈深度的其他差异。这导致了在实践中没有硬性限制的结论。你可能能够编写一个编译器管理的代码,可以毫无问题地编译,而另一个编译器不会出问题 - 这不是一个好主意,最大限度地解决这个问题。

毕竟,你的问题的代码可以写成:

  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);
返回值;
}

尽管我认为,您想到的更像是:

  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);
返回值;
}



<$ p ($函数,int ...参数){

返回IntStream.of(arguments).reduce(theFunction); $ p $ public static OptionalInt methodContainingMethod(
IntBinaryOperator theFunction,
}


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);
}

这篇关于嵌套BiFunction的深度(或限制)(如果有)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆