当前位置: 首页 > 面试题库 >

Lambda表达式与方法参考实现细节

山森
2023-03-14
问题内容

鉴于这种:

class MyClass {
    static class A {
        public boolean property() {
            return Math.random() < 0.5;
        }
    }

    static List<A> filterLambda(List<A> list) {
        return list.stream().filter(a -> a.property()).collect(Collectors.toList());
    }

    static List<A> filterMethodCall(List<A> list) {
        return list.stream().filter(A::property).collect(Collectors.toList());
    }
}
  • 编译器 对每种方法 执行的操作有什么 区别?
  • 如果有的话,内存使用或运行时间是否有所不同?(即使很小,问题也只是学术上的)

问题答案:

这是Brett Oken链接的Brian
Goetz的文档
的摘录:

当编译器遇到lambda表达式时,它首先将lambda主体降低(降低)到方法中
其参数列表和返回类型与lambda表达式的参数匹配,并可能带有一些其他参数(用于从词法范围捕获的值(如果有)。)在将捕获lambda表达式的点上,它会生成一个invokedynamic调用站点,调用时,该函数返回lambda转换为的功能接口的实例。此调用站点称为给定lambda的lambda工厂。lambda工厂的动态参数是从词法范围捕获的值。lambda工厂的bootstrap方法是Java语言运行时库中的一种标准化方法,称为lambda元工厂。静态引导程序参数捕获在编译时有关lambda的已知信息(将其转换为功能接口,

方法引用与lambda表达式的处理方式相同,不同之处在于,大多数方法引用不需要分解为新方法
;我们可以简单地为引用的方法加载一个常量方法句柄,并将其传递给元工厂。

从同一文档中提取的示例:

例如,考虑一个捕获字段minSize的lambda:

list.filter(e -> e.getSize() < minSize )

我们将其作为实例方法进行解糖,并将接收器作为第一个捕获的参数传递:

list.forEach(INDY((MH(metaFactory), MH(invokeVirtual Predicate.apply),
                    MH(invokeVirtual B.lambda$1))( this ))));

private boolean lambda$1(Element e) {
    return e.getSize() < minSize; }

list.filter(String::isEmpty)

被翻译为:

list.filter(indy(MH(metaFactory), MH(invokeVirtual Predicate.apply),
             MH(invokeVirtual String.isEmpty))()))


 类似资料:
  • IntelliJ一直建议我用方法引用替换我的lambda表达式。 两者之间有什么客观差异吗?

  • 本文向大家介绍Java8 Lambda表达式模板方法实现解析,包括了Java8 Lambda表达式模板方法实现解析的使用技巧和注意事项,需要的朋友参考一下 Java注解提供了关于代码的一些信息,但并不直接作用于它所注解的代码内容。在这个教程当中,我们将学习Java的注解,如何定制注解,注解的使用以及如何通过反射解析注解。 Java1.5引入了注解,当前许多java框架中大量使用注解,如Hibern

  • 问题内容: 我回答的问题让我感到奇怪: 如何在Python中实现正则表达式?有什么样的效率保证?实施是“标准”还是会更改? 我认为正则表达式将实现为DFA,因此非常有效(最多需要扫描输入字符串一次)。Laurence Gonsalves提出了一个有趣的观点,即并非所有的Python正则表达式都是正则表达式。(他的示例是r“(a +)b \1”,它与一定数量的a,ab匹配,然后与之前相同的a数量匹配

  • 问题内容: 可以将lambda表达式中的元素完成的操作链接/连接起来,如下所示: 有没有办法通过方法引用来做到这一点?像这样: 我知道我可以在四个单独的调用中执行此操作(它们也可以执行更多操作,即更改值): 我什至不能做这样简单的事情: 问题答案: 通过功能接口的默认方法可以链接。但是“问题”在于,当您返回合成表达式的右侧时,推理引擎没有足够的信息来确定左侧是相同的功能接口。 要提供该信息,您必须

  • 问题内容: 假设我有一个通用接口: 和方法sort: 我可以调用此方法并将lambda表达式作为参数传递: 那会很好的。 但是现在,如果我将接口设为非泛型,并且将方法设为泛型: 然后像这样调用: 它不会编译。它在lambda表达式中显示错误: “目标方法是通用的” 好的,当我使用编译时,它显示以下错误: 从此错误消息看来,编译器似乎无法推断类型参数。是这样吗 如果是,那为什么会这样呢? 我尝试了各

  • 它不编译。它在lambda表达式中显示错误: “目标方法是泛型的” 好的,当我使用编译它时,它显示了以下错误: