当前位置: 首页 > news >正文

Lambda原理及应用

Lambda原理及应用

Lambda介绍

Lambda 是 JDK8 以后版本推出的一个新特性,也是一个重要的版本更新,利用 Lambda 可以简化内部类,可以更方便的进行集合的运算,让你的代码看起来更加简洁,也能提升代码的运行效率

Lambda语法

非静态类

(parameters...) -> expression

或者

(parameters...) ->{ statements; }

静态类

(parameters...) -> Class.Method(parameters...)

通常也可以简写成

Class::Method

举个例子

() -> 1 
i -> 2 * i  
(String s) -> {System.out.print(s);}
(o1, o2) -> Integer.compare(o1, o2)
Integer::compare

Lambda的原理

例子

我们来看下面的例子,使用 Lambda 实现一个 Runable 线程。

package org.lin;public class LambdaTest {public static void main(String[] args) {new Thread(() -> System.out.println("run")).start();}
}

分析一下它的字节码:

// access flags 0x21
public class org/lin/LambdaTest {// compiled from: LambdaTest.java// access flags 0x19public final static INNERCLASS java/lang/invoke/MethodHandles$Lookup java/lang/invoke/MethodHandles Lookup// access flags 0x1public <init>()VL0LINENUMBER 3 L0ALOAD 0INVOKESPECIAL java/lang/Object.<init> ()VRETURNL1LOCALVARIABLE this Lorg/lin/LambdaTest; L0 L1 0MAXSTACK = 1MAXLOCALS = 1// access flags 0x9public static main([Ljava/lang/String;)VL0LINENUMBER 6 L0NEW java/lang/ThreadDUPINVOKEDYNAMIC run()Ljava/lang/Runnable; [// handle kind 0x6 : INVOKESTATICjava/lang/invoke/LambdaMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;// arguments:()V, // handle kind 0x6 : INVOKESTATICorg/lin/LambdaTest.lambda$main$0()V, ()V]INVOKESPECIAL java/lang/Thread.<init> (Ljava/lang/Runnable;)VINVOKEVIRTUAL java/lang/Thread.start ()VL1LINENUMBER 7 L1RETURNL2LOCALVARIABLE args [Ljava/lang/String; L0 L2 0MAXSTACK = 3MAXLOCALS = 1// access flags 0x100Aprivate static synthetic lambda$main$0()VL0LINENUMBER 6 L0GETSTATIC java/lang/System.out : Ljava/io/PrintStream;LDC "run"INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)VRETURNMAXSTACK = 2MAXLOCALS = 0
}

关键指令

  INVOKEDYNAMIC run()Ljava/lang/Runnable; [// handle kind 0x6 : INVOKESTATICjava/lang/invoke/LambdaMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;// arguments:()V, // handle kind 0x6 : INVOKESTATICorg/lin/LambdaTest.lambda$main$0()V, ()V]

通过调用一个 INVOKEDYNAMIC 指令 ,将方法链接到这个方法上 org/lin/LambdaTest.lambda$main$0()V

这个方法的命名方式 ,很可能 JDK 内部帮我们生成了一个内部类, org/lin/LambdaTest.lambda$main

通过 jclasslib 工具查看,验证了我们的想法:
在这里插入图片描述

Invokedynamic 和 LambdaMetafactory

Invokedynamic

Invokedynamic 是 JDK7 引入的一条新指令,通过一个调用点 CallSite 和 方法句柄 MethodHandle,来完成一个方法的调用。
CallSite 就是一个 MethodHandle 的 Holder,MethodHandle 指向一个调用点真正执行的方法。

LambdaMetafactory

LambdaMetafactory 是 JDK 内部 CallSite 和 MethodHandle 绑定实现类。

LambdaMetafactory的关键方法

public static CallSite metafactory(MethodHandles.Lookup caller,String invokedName,MethodType invokedType,MethodType samMethodType,MethodHandle implMethod,MethodType instantiatedMethodType)throws LambdaConversionException {AbstractValidatingLambdaMetafactory mf;mf = new InnerClassLambdaMetafactory(caller, invokedType,invokedName, samMethodType,implMethod, instantiatedMethodType,false, EMPTY_CLASS_ARRAY, EMPTY_MT_ARRAY);mf.validateMetafactoryArgs();return mf.buildCallSite();}
  • MethodHandles.Lookup caller – 调用者,也就是 Invokedynamic 指令运行的上下文,通常可以通过 Lookup#lookupClass() 获取。
  • String invokedName – Lambda 实现的接口的方法名称。
  • MethodType invokedType – 调用点的方法签名描述 ,
  • MethodType samMethodType – Lambda 实现的接口方法的签名描述 。(sam 就 single public abstract method 的缩写)
  • MethodHandle implMethod – 调用点的方法句柄。
  • MethodType instantiatedMethodType – 运行时调用点的方法签名描述。

参考:
https://zhuanlan.zhihu.com/p/28124632
https://www.jianshu.com/p/d74e92f93752
https://www.jianshu.com/p/7ef49246c176
https://www.cnblogs.com/wzqshb/p/16987548.html

相关文章:

Lambda原理及应用

Lambda原理及应用 Lambda介绍 Lambda 是 JDK8 以后版本推出的一个新特性&#xff0c;也是一个重要的版本更新&#xff0c;利用 Lambda 可以简化内部类&#xff0c;可以更方便的进行集合的运算&#xff0c;让你的代码看起来更加简洁,也能提升代码的运行效率。 Lambda语法 非…...

运动耳机推荐、最值得入手的运动耳机清单共享

现在市面上各式各样的运动蓝牙耳机着实让人挑花了眼,怎样才能从纷繁复杂的市场中挑选出专业性、安全性、舒适性等各个方面都做地可圈可点的运动蓝牙耳机可真不是一件易事啊&#xff0c;甚至连不少老朋友都会踩坑&#xff0c;为了能让大家挑到真正的运动蓝牙耳机&#xff0c;为此…...

c盘爆满--如何清理电脑C盘

问题 c盘饱满很多天了&#xff0c;今天终于忍无可忍&#xff0c;开始展开对c盘的处理 c盘的基本处理有两步&#xff0c; 第一步&#xff0c;电脑系统清理 1,c盘右键属性&#xff0c;有个磁盘清理&#xff0c;好像是系统更新的一些缓存资源&#xff0c;可以直接清理 当然这只…...

Nginx配置web服务器及部署反向代理

Nginx配置web服务器及部署反向代理配置web服务器location语法部署反向代理代理转发配置web服务器 项目部署到linux上的静态文件代理给Nginx处理。当访问服务器IP时&#xff0c;可以自动返回静态文件主页。 主配置文件中server块对应的次配置include /etc/nginx/conf.d/*.conf…...

mvvm和mvc

mvvm是model-view-viewmodel的缩写&#xff0c;前端开发的架构模式 m&#xff1a; model&#xff1a;模型&#xff0c;指的是数据和交互业务逻辑 v&#xff1a; view&#xff1a;视图&#xff0c;用户看到的ui界面 vm&#xff1a; viewmodel&#xff1a;视图模型&#xff0…...

JavaScript while 循环

JavaScript while 循环的目的是为了反复执行语句或代码块。只要指定条件为 true&#xff0c;循环就可以一直执行代码块。while 循环while 循环会在指定条件为真时循环执行代码块。语法while (条件){需要执行的代码 }实例本例中的循环将继续运行&#xff0c;只要变量 i 小于 5&a…...

CMU15-445 Project.0总结

在线测试 本地测试 Project #0 - C Primer 以下是Project #0的网址&#xff0c;2022FALL的Project #0本质上是实现一棵字典树&#xff0c;关于字典树的相关内容可以参考C实现字典树。 在本题中&#xff0c;为了存储对应着字符串的任意类型值&#xff0c;题目设计了一个Tri…...

计算机网络题库---错题本

&#xff08;一&#xff09;老生常谈 第一章&#xff1a; 1.什么是计算机网络&#xff1f;其主要功能是什么&#xff1f; 解答&#xff1a; 利用通信设备和线路&#xff0c;将分布在地理位置不同的、功能独立的多个计算机系统连接起来&#xff0c;以功能完善的网络软件实现网…...

【react】react创建项目与引入AntD组件库:

文章目录一、初始化项目&#xff1a;【1】创建项目【2】暴露项目配置文件【3】安装依赖【4】配置less二、快捷键&#xff1a;【1】rcctab三、安装AntD组件库&#xff1a;【1】安装【2】index.js【3】问题&#xff1a;【4】效果&#xff1a;一、初始化项目&#xff1a; 【1】创…...

hook与mixin

看完vue3就开始看vue3的源码&#xff0c;表示很懵~ 刚把rollup打包搞完&#xff0c;这不响应式就接着来了&#xff01;&#xff0c;还是写篇直接使用vue3的博客清清脑吧&#xff01; 什么是hook、mixin&#xff1f; mixin: Vue2中多个组件内存在重复JS业务逻辑&#xff0c;使…...

【C语言】自定义类型

一、什么是自定义类型C语言提供了丰富的内置类型&#xff0c;常见的有int, char, float, double, 以及各种指针。除此之外&#xff0c;我们还能自己创建一些类型&#xff0c;这些类型称为自定义类型&#xff0c;如数组&#xff0c;结构体&#xff0c;枚举类型和联合体类型。二、…...

没有上司的舞会(C++,树形DP)

题目描述 某大学有 nnn 个职员&#xff0c;编号为 1…n1\ldots n1…n。 他们之间有从属关系&#xff0c;也就是说他们的关系就像一棵以校长为根的树&#xff0c;父结点就是子结点的直接上司。 现在有个周年庆宴会&#xff0c;宴会每邀请来一个职员都会增加一定的快乐指数 ri…...

【java基础】static和final关键字的作用及其用法详解

文章目录static关键字静态字段静态方法静态代码块静态内部类final关键字final字段final方法final类static关键字 这个关键字表示静态的&#xff0c;用于不同地方意思不一样 静态字段 如果我们将其作用到字段上&#xff0c;那么该字段为类所拥有&#xff0c;我们使用new关键字…...

#集成学习#:bagging、boosting、stacking和blending

集成学习是一种机器学习方法&#xff0c;旨在提高单个模型的性能和鲁棒性。它基于这样一个假设&#xff1a;通过结合多个模型的预测结果&#xff0c;可以获得更好的预测性能&#xff0c;因为每个模型都可能从数据中提取不同的信息&#xff0c;因此他们的错误也可能是不同的&…...

NCRE计算机等级考试Python真题(一)

第一套试题1、关于数据的存储结构&#xff0c;以下选项描述正确的是A.数据所占的存储空间量B.数据在计算机中的顺序存储方式C.数据的逻辑结构在计算机中的表示D.存储在外存中的数据正确答案&#xff1a; C2、关于线性链表的描述&#xff0c;以下选项中正确的是A.存储空间不一定…...

C#协变逆变

文章目录协变协变接口的实现逆变里氏替换原则协变 协变概念令人费解&#xff0c;多半是取名或者翻译的锅&#xff0c;其实是很容易理解的。 比如大街上有一只狗&#xff0c;我说大家快看&#xff0c;这有一只动物&#xff01;这个非常自然&#xff0c;虽然动物并不严格等于狗…...

算法设计与分析期末考试复习(四)

贪心算法&#xff08;Greedy Algorithm&#xff09; 找零钱问题 假设有4种硬币&#xff0c;面值分别为&#xff1a;二角五分、一角、五分和一分&#xff0c;现在要找给顾客六角三分钱&#xff0c;如何找使得给出的硬币个数最少&#xff1f; 首先选出1个面值不超过六角三分的最…...

qsort函数排序数据 and 模拟实现qosrt函数(详解)

前言&#xff1a;内容包括使用库函数qsort排序任意类型的数据&#xff0c;模拟实现qsort函数&#xff08;冒泡排序的逻辑&#xff09; 我们先了解qsort函数的语法&#xff1a;qsort函数默认按照升序排序数据 void qsort (void* base, size_t num, size_t size,int (*compar)(…...

Mysql视图,存储过程,触发器,函数以及Mysql架构

一,视图视图是基于查询的一个虚拟表 , 也就是将sql语句封装起来, 要用的时候直接调用视图即可, select语句查询的表称为基表, 查询的结果集称为虚拟表, 基本表数据发生了改变, 那么视图也会发生改变, 使用视图就是为了简化查询语句.1.CREATE VIEW view_admin AS SELECT * FROM…...

什么是线程死锁?如何解决死锁问题

死锁&#xff0c;一组互相竞争的资源的线程之间相互等待&#xff0c;导致永久阻塞的现象。 如下图所示&#xff1a; 与死锁对应的&#xff0c;还有活锁&#xff0c;是指线程没有出现阻塞&#xff0c;但是无限循环。 有一个经典的银行转账例子如下&#xff1a; 我们有个账户类…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)

概述 在 Swift 开发语言中&#xff0c;各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过&#xff0c;在涉及到多个子类派生于基类进行多态模拟的场景下&#xff0c;…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

css的定位(position)详解:相对定位 绝对定位 固定定位

在 CSS 中&#xff0c;元素的定位通过 position 属性控制&#xff0c;共有 5 种定位模式&#xff1a;static&#xff08;静态定位&#xff09;、relative&#xff08;相对定位&#xff09;、absolute&#xff08;绝对定位&#xff09;、fixed&#xff08;固定定位&#xff09;和…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版

7种色调职场工作汇报PPT&#xff0c;橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版&#xff1a;职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...