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

Java对象复制系列二: 手把手带你写一个Apache BeanUtils

👆🏻👆🏻👆🏻关注博主,让你的代码变得更加优雅。

前言

Apache BeanUtils 是Java中用来复制2个对象属性的一个类型。

上一篇文章我们讲到了 Apache BeanUtils 性能相对比较差,今天我不仅仅要带你学习源代码 ,更要带你手把手写一个Apache BeanUtils。

最佳实践

直接上案例

案例地址: https://github.com/zhuangjiaju/easytools/blob/main/easytools-test/src/test/java/com/github/zhuangjiaju/easytools/test/demo/beanutils/ApacheBeanUtilsTest.java

简单的复制对象

直接上代码:

创建一个java 对象:

/*** Apache BeanUtils 使用的demo*/
@Test
public void demo() throws Exception {BeanUtilsDemoDTO beanUtilsDemo = new BeanUtilsDemoDTO();beanUtilsDemo.setId("id");beanUtilsDemo.setFirstName("firstName");BeanUtilsDemoDTO newBeanUtilsDemo = new BeanUtilsDemoDTO();BeanUtils.copyProperties(newBeanUtilsDemo, beanUtilsDemo);log.info("newBeanUtilsDemo: {}", newBeanUtilsDemo);
}

输出结果:

     20:21:56.949 [main] INFO com.github.zhuangjiaju.easytools.test.demo.beanutils.ApacheBeanUtilsTest -- newBeanUtilsDemo: BeanUtilsDemoDTO(id=id, firstName=firstName, lastName=null, age=null, email=null, phoneNumber=null, address=null, city=null, state=null, country=null, major=null, gpa=null, department=null, yearOfStudy=null, advisorName=null, enrollmentStatus=null, dormitoryName=null, roommateName=null, scholarshipDetails=null, extracurricularActivities=null)

可见已经复制对象成功了,输出里面有 firstName 的值。

直接自己写一个简单的 BeanUtils

源码有点复杂,我先直接写一个简单的 BeanUtils,非常的通俗易懂,看懂了然后再看源代码就非常容易了。

复制的代码一模一样:

/*** 自己写一个简单的 BeanUtils*/
@Test
public void custom() throws Exception {BeanUtilsDemoDTO beanUtilsDemo = new BeanUtilsDemoDTO();beanUtilsDemo.setId("id");beanUtilsDemo.setFirstName("firstName");BeanUtilsDemoDTO newBeanUtilsDemo = new BeanUtilsDemoDTO();MyBeanUtils.copyProperties(newBeanUtilsDemo, beanUtilsDemo);log.info("newBeanUtilsDemo: {}", newBeanUtilsDemo);
}

我们自己实现的工具类:

前置知识:

Introspector.getBeanInfo: 是 Java 自带的一个类,可以获取一个类的 BeanInfo 信息,然后获取属性的描述资料 PropertyDescriptor
BeanInfo : bean 的描述信息
PropertyDescriptor: bean 的属性的资料信息 ,可以获取到属性的 get/set 方法
Method: 方法,用这个对象可以反射掉调用

 public static class MyBeanUtils {/*** 复制方法** @param dest* @param orig* @throws Exception*/public static void copyProperties(Object dest, Object orig) throws Exception {// 获取目标对象的 PropertyDescriptor 属性资料PropertyDescriptor[] destPropertyDescriptors = Introspector.getBeanInfo(dest.getClass(), Object.class).getPropertyDescriptors();// 获取来源对象的 PropertyDescriptor 属性资料PropertyDescriptor[] origPropertyDescriptors = Introspector.getBeanInfo(orig.getClass(), Object.class).getPropertyDescriptors();// 上面2个 在 Apache BeanUtils 还加了缓存// 循环目标对象for (PropertyDescriptor propertyDescriptor : destPropertyDescriptors) {// 获取属性名String name = propertyDescriptor.getName();// 循环来源对象的属性名for (PropertyDescriptor origPropertyDescriptor : origPropertyDescriptors) {// 2个属性名匹配上了if (name.equals(origPropertyDescriptor.getName())) {// 直接获取 method 然后反色调用即可 就设置了数据propertyDescriptor.getWriteMethod().invoke(dest,origPropertyDescriptor.getReadMethod().invoke(orig));break;}}}}
}

代码是不是非常的容易?就是循环目标对象的属性,然后循环来源对象的属性,然后匹配上了就反射调用即可。

和 Apache BeanUtils 的源码逻辑基本一样,只是没有加缓存之类的。

源码解析

org.apache.commons.beanutils.BeanUtils.copyProperties

public static void copyProperties(final Object dest, final Object orig)throws IllegalAccessException, InvocationTargetException {// BeanUtilsBean 放在了 ThreadLocal 里面,所以是不可以并发的,但是通过 ThreadLocal 保障了BeanUtilsBean不会并发 也不会每次都new // 直接调用 copyPropertiesBeanUtilsBean.getInstance().copyProperties(dest, orig);
}

org.apache.commons.beanutils.BeanUtilsBean.copyProperties

 public void copyProperties(final Object dest, final Object orig)throws IllegalAccessException, InvocationTargetException {// Validate existence of the specified beansif (dest == null) {throw new IllegalArgumentException("No destination bean specified");}if (orig == null) {throw new IllegalArgumentException("No origin bean specified");}if (log.isDebugEnabled()) {log.debug("BeanUtils.copyProperties(" + dest + ", " +orig + ")");}// Copy the properties, converting as necessaryif (orig instanceof DynaBean) {final DynaProperty[] origDescriptors =((DynaBean)orig).getDynaClass().getDynaProperties();for (DynaProperty origDescriptor : origDescriptors) {final String name = origDescriptor.getName();// Need to check isReadable() for WrapDynaBean// (see Jira issue# BEANUTILS-61)if (getPropertyUtils().isReadable(orig, name) &&getPropertyUtils().isWriteable(dest, name)) {final Object value = ((DynaBean)orig).get(name);copyProperty(dest, name, value);}}} else if (orig instanceof Map) {@SuppressWarnings("unchecked")final// Map properties are always of type <String, Object>Map<String, Object> propMap = (Map<String, Object>)orig;for (final Map.Entry<String, Object> entry : propMap.entrySet()) {final String name = entry.getKey();if (getPropertyUtils().isWriteable(dest, name)) {copyProperty(dest, name, entry.getValue());}}} else /* if (orig is a standard JavaBean) */ {// 这里比较核心 获取来源的PropertyDescriptor 属性资料 和我们自己实现的代码 一样// getPropertyDescriptors 我们会继续跟进final PropertyDescriptor[] origDescriptors =getPropertyUtils().getPropertyDescriptors(orig);// 循环来源的 属性资料for (PropertyDescriptor origDescriptor : origDescriptors) {final String name = origDescriptor.getName();if ("class".equals(name)) {continue; // No point in trying to set an object's class}if (getPropertyUtils().isReadable(orig, name) &&getPropertyUtils().isWriteable(dest, name)) {try {final Object value =getPropertyUtils().getSimpleProperty(orig, name);// 调用复制参数 // copyProperty 我们会继续跟进copyProperty(dest, name, value);} catch (final NoSuchMethodException e) {// Should not happen}}}}}

org.apache.commons.beanutils.PropertyUtilsBean.getPropertyDescriptors(java.lang.Object)
org.apache.commons.beanutils.PropertyUtilsBean.getPropertyDescriptors(java.lang.Class<?>)
org.apache.commons.beanutils.PropertyUtilsBean.getIntrospectionData

  private BeanIntrospectionData getIntrospectionData(final Class<?> beanClass) {if (beanClass == null) {throw new IllegalArgumentException("No bean class specified");}// Look up any cached information for this bean class// 和我们自己写的比,这里核心是加了一个descriptorsCache 的缓存 BeanIntrospectionData data = descriptorsCache.get(beanClass);if (data == null) {data = fetchIntrospectionData(beanClass);descriptorsCache.put(beanClass, data);}return data;
}

org.apache.commons.beanutils.PropertyUtilsBean.fetchIntrospectionData
org.apache.commons.beanutils.DefaultBeanIntrospector.introspect

 public void introspect(final IntrospectionContext icontext) {BeanInfo beanInfo = null;try {// 这里和我们自己实现的一样 可以获取一个类的 BeanInfo 信息beanInfo = Introspector.getBeanInfo(icontext.getTargetClass());} catch (final IntrospectionException e) {// no descriptors are added to the contextlog.error("Error when inspecting class " + icontext.getTargetClass(),e);return;}//  获取 bean 的 PropertyDescriptor 属性的资料信息PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();if (descriptors == null) {descriptors = new PropertyDescriptor[0];}handleIndexedPropertyDescriptors(icontext.getTargetClass(),descriptors);icontext.addPropertyDescriptors(descriptors);
}

通过以上方法,我们就拿到了 PropertyDescriptor[] origDescriptors 接下来我们看 copyProperty

org.apache.commons.beanutils.BeanUtilsBean.copyProperty

public void copyProperty(final Object bean, String name, Object value)throws IllegalAccessException, InvocationTargetException {// Trace logging (if enabled)if (log.isTraceEnabled()) {final StringBuilder sb = new StringBuilder("  copyProperty(");sb.append(bean);sb.append(", ");sb.append(name);sb.append(", ");if (value == null) {sb.append("<NULL>");} else if (value instanceof String) {sb.append((String)value);} else if (value instanceof String[]) {final String[] values = (String[])value;sb.append('[');for (int i = 0; i < values.length; i++) {if (i > 0) {sb.append(',');}sb.append(values[i]);}sb.append(']');} else {sb.append(value.toString());}sb.append(')');log.trace(sb.toString());}// Resolve any nested expression to get the actual target beanObject target = bean;final Resolver resolver = getPropertyUtils().getResolver();while (resolver.hasNested(name)) {try {target = getPropertyUtils().getProperty(target, resolver.next(name));name = resolver.remove(name);} catch (final NoSuchMethodException e) {return; // Skip this property setter}}if (log.isTraceEnabled()) {log.trace("    Target bean = " + target);log.trace("    Target name = " + name);}// Declare local variables we will requirefinal String propName = resolver.getProperty(name); // Simple name of target propertyClass<?> type = null;                         // Java type of target propertyfinal int index = resolver.getIndex(name);         // Indexed subscript value (if any)final String key = resolver.getKey(name);           // Mapped key value (if any)// Calculate the target property typeif (target instanceof DynaBean) {final DynaClass dynaClass = ((DynaBean)target).getDynaClass();final DynaProperty dynaProperty = dynaClass.getDynaProperty(propName);if (dynaProperty == null) {return; // Skip this property setter}type = dynaPropertyType(dynaProperty, value);} else {PropertyDescriptor descriptor = null;try {descriptor =getPropertyUtils().getPropertyDescriptor(target, name);if (descriptor == null) {return; // Skip this property setter}} catch (final NoSuchMethodException e) {return; // Skip this property setter}type = descriptor.getPropertyType();if (type == null) {// Most likely an indexed setter on a POJB onlyif (log.isTraceEnabled()) {log.trace("    target type for property '" +propName + "' is null, so skipping ths setter");}return;}}if (log.isTraceEnabled()) {log.trace("    target propName=" + propName + ", type=" +type + ", index=" + index + ", key=" + key);}// Convert the specified value to the required type and store itif (index >= 0) {                    // Destination must be indexedvalue = convertForCopy(value, type.getComponentType());try {getPropertyUtils().setIndexedProperty(target, propName,index, value);} catch (final NoSuchMethodException e) {throw new InvocationTargetException(e, "Cannot set " + propName);}} else if (key != null) {            // Destination must be mapped// Maps do not know what the preferred data type is,// so perform no conversions at all// FIXME - should we create or support a TypedMap?try {getPropertyUtils().setMappedProperty(target, propName,key, value);} catch (final NoSuchMethodException e) {throw new InvocationTargetException(e, "Cannot set " + propName);}} else {                             // Destination must be simplevalue = convertForCopy(value, type);try {// 核心我们看这里 设置属性值getPropertyUtils().setSimpleProperty(target, propName, value);} catch (final NoSuchMethodException e) {throw new InvocationTargetException(e, "Cannot set " + propName);}}}

org.apache.commons.beanutils.PropertyUtilsBean.setSimpleProperty

public void setSimpleProperty(final Object bean,final String name, final Object value)throws IllegalAccessException, InvocationTargetException,NoSuchMethodException {if (bean == null) {throw new IllegalArgumentException("No bean specified");}if (name == null) {throw new IllegalArgumentException("No name specified for bean class '" +bean.getClass() + "'");}// Validate the syntax of the property nameif (resolver.hasNested(name)) {throw new IllegalArgumentException("Nested property names are not allowed: Property '" +name + "' on bean class '" + bean.getClass() + "'");} else if (resolver.isIndexed(name)) {throw new IllegalArgumentException("Indexed property names are not allowed: Property '" +name + "' on bean class '" + bean.getClass() + "'");} else if (resolver.isMapped(name)) {throw new IllegalArgumentException("Mapped property names are not allowed: Property '" +name + "' on bean class '" + bean.getClass() + "'");}// Handle DynaBean instances speciallyif (bean instanceof DynaBean) {final DynaProperty descriptor =((DynaBean)bean).getDynaClass().getDynaProperty(name);if (descriptor == null) {throw new NoSuchMethodException("Unknown property '" +name + "' on dynaclass '" +((DynaBean)bean).getDynaClass() + "'");}((DynaBean)bean).set(name, value);return;}// Retrieve the property setter method for the specified propertyfinal PropertyDescriptor descriptor =getPropertyDescriptor(bean, name);if (descriptor == null) {throw new NoSuchMethodException("Unknown property '" +name + "' on class '" + bean.getClass() + "'");}// 通过 PropertyDescriptor 获取道理 set 方法 的 Methodfinal Method writeMethod = getWriteMethod(bean.getClass(), descriptor);if (writeMethod == null) {throw new NoSuchMethodException("Property '" + name +"' has no setter method in class '" + bean.getClass() + "'");}// Call the property setter methodfinal Object[] values = new Object[1];values[0] = value;if (log.isTraceEnabled()) {final String valueClassName =value == null ? "<null>" : value.getClass().getName();log.trace("setSimpleProperty: Invoking method " + writeMethod+ " with value " + value + " (class " + valueClassName + ")");}// 这个方法就是 简单的 writeMethod 调用 invoke 方法 这样子我们的值就设置好了invokeMethod(writeMethod, bean, values);

好了,这样子一个值就复制到新的对象里面了,是不是很简单?

总结

今天学习了 Apache BeanUtils 的源码,总体上就是一个缓存+反射的调用,看是记不住的,大家赶快打开自己的电脑跟几遍源码吧。

后面还会带大家看 Spring BeanUtils 的源码,欢迎持续关注。

写在最后

给大家推荐一个非常完整的Java项目搭建的最佳实践,也是本文的源码出处,由大厂程序员&EasyExcel作者维护,地址:https://github.com/zhuangjiaju/easytools

相关文章:

Java对象复制系列二: 手把手带你写一个Apache BeanUtils

&#x1f446;&#x1f3fb;&#x1f446;&#x1f3fb;&#x1f446;&#x1f3fb;关注博主&#xff0c;让你的代码变得更加优雅。 前言 Apache BeanUtils 是Java中用来复制2个对象属性的一个类型。 上一篇文章我们讲到了 Apache BeanUtils 性能相对比较差&#xff0c;今天…...

一个极简的 Vue 示例

https://andi.cn/page/621516.html...

修复 Ubuntu 24.04 Dock 丢失应用程序图标

找出应用程序窗口的类名 首先&#xff0c;您需要启动应用程序窗口。然后&#xff0c;按 Alt F2 启动“运行 Command”对话框。当对话框打开时&#xff0c;输入 lg 并按 Enter 键。 在该窗口中&#xff0c;单击Windows按钮&#xff0c;然后找出目标应用程序窗口的类名称。 在/…...

idea MarketPlace插件找不到

一、背景 好久没用idea了&#xff0c;打开项目后没有lombok&#xff0c;安装lombok插件时发现idea MarketPlace插件市场找不到&#xff0c;需要重新配置代理源&#xff0c;在外网访问时通过代理服务进行连接 二、操作 ### File-->setting 快捷键 Ctrl Alt S 远端源地…...

windows下使用编译opencv在qt中使用

记录一下&#xff1a;在windows下qt使用opencv 1、涉及需要下载的软件 CMake 下载地址opecnv下载地址mingw(需要配置环境变量) 这个在下载qt的时候可以直接安装一般在qt的安装路径下的tool里比如我的安装路径 (C:\zz\ProgramFiles\QT5.12\Tools\mingw730_64) 2、在安装好CMake…...

正则表达式-使用笔记

正则使用不当&#xff0c;会导致CPU飙升&#xff1b;场景区分&#xff0c;是判断存在还是提取内容&#xff1b;匹配范围&#xff0c;是匹配部分内容还是整行&#xff1b; 一、初识正则 正则表达式 – 语法 | 菜鸟教程 sparksql 正则匹配总结 https://www.cnblogs.com/he1m4n…...

C语言中的数组:掌握数据的有序集合【一维数组,二维数组,字符串数组,直方图打印,计算全排列,字符数组常用函数】

目录 C语言中的数组&#xff1a;掌握数据的有序集合【一维数组&#xff0c;二维数组&#xff0c;字符串数组】一维数组一维数组的创建数组的七种初始化完全初始化&#xff1a;部分初始化&#xff1a;字符数组的初始化&#xff1a;自动初始化为0&#xff1a;使用memset函数初始化…...

软件架构之计算机网络

软件架构之计算机网络 第 4 章 计算机网络4.1 网络架构与协议4.1.1 网络互联模型4.1.2 常见的网络协议4.1.3 IPv6 4.2 局域网与广域网4.2.2 无线局域网4.2.3 广域网技术4.2.4 网络接入技术 4.3 网络互连与常用设备4.4 网络工程4.4.1 网络规划4.4.2 网络设计4.4.3 网络实施 4.5 …...

Qt/C++项目积累: 2.主机监控器 - 2.2 历史功能实现

修订历史&#xff1a; 20240711&#xff1a;初始表设计&#xff0c;采用sqlite 正文&#xff1a; 关于历史数据存储&#xff0c;考虑的是用数据库来完成&#xff0c;目前考虑使用Sqlite和mysql&#xff0c;先用sqlite来实现&#xff0c;设计表过程如下&#xff1a; 机器总览…...

初识Spring Web MVC

1. 什么是 Spring Web MVC&#xff1f; Spring Web MVC 是基于 Servlet API 构建的原始 Web 框架&#xff0c;从⼀开始就包含在 Spring 框架中。它的正式名称“Spring Web MVC”来⾃其源模块的名称(Spring-webmvc)&#xff0c;但它通常被称为"SpringMVC".Servlet&am…...

【排序算法】归并排序

目录 一.基本思想 二.递归版本 三.非递归版本 四.特性总结 1.时间复杂度&#xff1a;O(N*logN) 2.空间复杂度&#xff1a;O(N) 3.稳定性&#xff1a;稳定 一.基本思想 归并排序是采用分治法的一个非常典型的应用。它将已经有序的序列合并为完全有序的序列&#xff0c;即…...

游戏AI的创造思路-技术基础-决策树(2)

上一篇写了决策树的基础概念和一些简单例子&#xff0c;本篇将着重在实际案例上进行说明 目录 8. 决策树应用的实际例子 8.1. 方法和过程 8.1.1. 定义行为 8.1.2. 确定属性 8.1.3. 构建决策树 8.1.4. 实施行为 8.1.5. 实时更新 8.2. Python代码 8. 决策树应用的实际例子…...

vue缓存页面,当tab切换时保留原有的查询条件

需求&#xff1a; 切换tab时&#xff0c;查询条件不变 路由页面&#xff1a; 单个页面上加这句话&#xff1a;...

PythonConda系列(亲测有效):【解决方案】Collecting package metadata (current_repodata.json): failed

【解决方案】Collecting package metadata (current_repodata.json&#xff09;: failed 问题描述解决方案小结参考文献 问题描述 在cmd下运行&#xff1a;conda install pylint -y&#xff0c;报错如下&#xff1a; C:\Users\apr> conda install --name apr pylint -y Co…...

web前端开发——标签一(注释、标题、段落、换行、格式、图片)

今天我来针对web前端开发讲解标签一 目录 html标签_标题&段落&换行 注释标签&#xff1a;Ctrl/ 标题标签&#xff1a; h1-h6 段落标签&#xff1a; 换行标签: 格式标签 图片标签_src属性 html标签_标题&段落&换行 注释标签&#xff1a;Ctrl/ Ctrl/ &…...

Django 常见的操作符

在filter() 方法&#xff0c;exclude() 方法中使用大于&#xff0c;小于&#xff0c;模糊匹配等操作符。 常见的操作符如下&#xff1a; 操作符含义示例等于Book.objects.filter(price10)! 或 __ne不等于用于查找字段不等于特定值的记录。但更常用exclude()方法。__gt大于用于…...

AJAX是什么?原生语法格式?jQuery提供分装好的AJAX有什么区别?

ajax 的全称 Asynchronous JavaScript and XML (异步 JavaScript 和 XML)。 AJAX是一种创建交互式网页应用的网页开发技术。其中最核心的依赖是浏览器提供的 XMLHttpRequest 对象&#xff0c;是这个对象使得浏览器可以发出 HTTP 请求与接收 HTTP 响应。实现了在页 面不刷新的…...

docker基础知识以及windows上的docker desktop 安装

记录以供备忘 基础概念&#xff1a; 什么是docker 将程序和环境一起打包&#xff0c;以在不同操作系统上运行的工具软件 什么是基础镜像 选一个基础操作系统和语言后&#xff0c;将对应的文件系统、依赖库、配置等打包为一个类似压缩包的文件&#xff0c;就是基础镜像 什么是…...

【深度学习基础】环境搭建 linux系统下安装pytorch

目录 一、anaconda 安装二、创建pytorch1. 创建pytorch环境&#xff1a;2. 激活环境3. 下载安装pytorch包4. 检查是否安装成功 一、anaconda 安装 具体的安装说明可以参考我的另外一篇文章【环境搭建】Linux报错bash: conda: command not found… 二、创建pytorch 1. 创建py…...

【Sql Server】sql server 2019设置远程访问,外网服务器需要设置好安全组入方向规则

大家好&#xff0c;我是全栈小5&#xff0c;欢迎来到《小5讲堂》。 这是《Sql Server》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。 温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 目录 前言1、无法链接…...

idea启动vue项目一直卡死在51%,问题分析及其如何解决

如果你的项目也一直卡在百分之几十&#xff0c;你可以参考下面的方法&#xff0c;试一试能否解决 问题描述&#xff1a; 通过在idea终端中输入命令 npm run serve 启动vue项目&#xff0c;启动进程一直卡在51% 如何解决&#xff1a; 检查 < template > 标签中的html内容…...

基于STM32设计的智能喂养系统(ESP8266+微信小程序)175

基于STM32设计的牛羊喂养系统(微信小程序)(175) 文章目录 一、前言1.1 项目介绍【1】项目功能介绍【2】项目硬件模块组成【3】ESP8266工作模式配置【4】上位机开发【5】项目模块划分1.2 项目功能需求1.3 项目开发背景1.4 开发工具的选择1.5 系统框架图1.6 系统原理图1.7 硬件实…...

第三方支付平台如何完美契合游戏行业?

在数字经济的浪潮中&#xff0c;游戏行业以其独特的魅力和创新能力&#xff0c;成为全球文化和经济交流的重要桥梁。然而&#xff0c;海外游戏商在进军中国市场时&#xff0c;常面临一系列难题。本文将通过一个故事案例&#xff0c;揭示第三方支付平台PASSTO PAY如何帮助海外游…...

计算机网络 5.6网桥与交换机

第六节 网桥与交换机 一、认识网桥 1.功能&#xff1a;连接两个具有相同或相似的网络结构的网络&#xff0c;解决网络之间距离太远问题&#xff0c;提高网络可靠性&#xff0c;还可以起过滤帧的作用而提高网络的性能。 2.适用场合&#xff1a;同构网。 3.特点&#xff1a; …...

CDH实操--集群卸载

作者&#xff1a;耀灵 1、停止正在运行的服务 a、控制台停止集群服务 b、控制台停止Cloudera Management Service c、命令行停止cm服务 systemctl stop cloudera-scm-agent #所有节点执行 systemctl stop cloudera-scm-server #cdh01节点执行2、主线并移除Parcles rm -r…...

5G RedCap调查报告

一、5G RedCap技术背景 5G RedCap(Reduced Capability缩写,轻量化5G),是3GPP标准化组织定义下的5G裁剪版本,是5G面向中高速率连接场景的物联网技术,它的能力介于5G NR(含eMBB和uRLLC)和LPWA(如LTE-M和NR-IoT)之间,如图1所示,是5G-A(5G Advanced)的关键技术之一。…...

模型(卷积、fc、attention)计算量 MAC/FLOPs 的手动统计方法

文章目录 简介背景为什么理解神经网络中的MAC和FLOPs很重要&#xff1f;资源效率内存效率能耗功耗效率 模型优化性能基准研究与发展 FLOPs 和 MACs 定义1. 全连接层 FLOPs 计算步骤 1&#xff1a;识别层参数步骤 2&#xff1a;计算 FLOPs 和 MACs步骤 3&#xff1a;总结结果使用…...

Git 删除包含敏感数据的历史记录及敏感文件

环境 Windows 10 Git 2.41.0 首先备份你需要删除的文件&#xff08;如果还需要的话&#xff09;&#xff0c;因为命令会将本地也删除将项目中修改的内容撤回或直接提交到仓库中&#xff08;有修改内容无法提交&#xff09; 会提示Cannot rewrite branches: You have unstaged …...

vue-tabs标签页引入其他页面

tabs页面 <template> <div class"app-container"> <el-tabs v-model"activeName" type"card" tab-click"handleClick"> <el-tab-pane label"套餐用户列表" name"first"> <user-list r…...

U-net和U²-Net网络详解

目录 U-Net: Convolutional Networks for Biomedical Image Segmentation摘要U-net网络结构pixel-wise loss weight U-Net: Going Deeper with Nested U-Structure for Salient Object Detection摘要网络结构详解整体结构RSU-n结构RSU-4F结构saliency map fusion module -- 显著…...

做旅游网站的关注与回复/seo搜索引擎优化技术教程

...

做网站的人是什么职位/全球疫情最新数据

案例一 导入图片思路: 1.导入库 2.加载图片 3.创建窗口 4.显示图片 5.暂停窗口 6.关闭窗口# 1.导入库import cv2# 2.加载图片img cv2.imread(a.png)# 3.创建窗口cv2.namedWindow(window 1 haha)# 4.显示图片cv2.imshow(window 1,img)# 5.暂停窗口cv2.waitKey(0)# 6.关闭窗口cv…...

天津网站建设普斯泰/百度查重

Flutter 在 Build完成后的监听和每一帧绘制完成后的监听 这个是我们监听要用的重要的类------->WidgetsBinding 官方是这么描述它的 The glue between the widgets layer and the Flutter engine. 中文的意思是 控件层和Flutter引擎之间的粘合剂。就是这个类 它能监听到…...

网站制作尺寸/网络营销的四个特点

声音也可以搜索了&#xff0c;可不是MP3搜索&#xff01; 向东博客 Findsounds的声音搜索不同于国内的某些MP3的搜索引擎&#xff0c;它可以可以搜索波…...

建设集团有限公司网站/热搜榜排名今日事件

我有一个问题,我不确定如何在假定DDD并使用C#/ EF Core时解决.简化情况&#xff1a;我们有2个聚合 – 项目和仓库.它们中的每一个都具有ExternalId(Guid)的身份以在外部(FE等)识别它,其也被视为其域身份.它还有数据库Id taht在数据库模型中表示它 – 实体模型和Db模型是同一类,…...

东莞网站建设lhznkj/seo外包网站

Linux中使用curl命令出现403错误的解决办法 403错误&#xff0c;是网站访问过程中&#xff0c;常见的错误提示&#xff0c;资源不可用&#xff0c; 服务器理解客户请求&#xff0c;但拒绝处理它&#xff0c;通常由于服务器上文件或目录的权限设置导致&#xff0c; 比如IIS或者a…...