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

MapStruct应用实战及BeanUtils性能比较

目录

    • 1、MapStruct介绍
    • 2、应用设置
      • 2.1 Maven依赖
    • 3、功能实战
      • 3.1 常用注解
      • 3.2 基本映射
        • 3.2.1 定义映射器的Java接口
        • 3.2.2 测试验证
      • 3.3 参数引用映射
        • 3.3.1 定义映射器的Java接口
        • 3.3.2 测试验证
      • 3.4 多对象参数映射
        • 3.4.1 定义映射器的Java接口
        • 3.4.2 测试验证
        • 3.4.3 注意点
      • 3.5 嵌套映射
        • 3.5.1 定义映射器的Java接口
        • 3.5.2 测试验证
        • 3.5.3 注意点
      • 3.6 对象更新
        • 3.6.1 定义映射器的Java接口
        • 3.6.2 测试验证
        • 3.6.3 注意点
    • 4、性能比较
      • 4.1 Apache BeanUtils 与 MapStruct比较
      • 4.2 Hutool BeanUtil与 MapStruct比较
      • 4.3 Spring BeanUtils 与 MapStruct比较
      • 4.4 Cglib BeanCopier 与 MapStruct比较
      • 4.4 性能对比结果(5次平均值)


1、MapStruct介绍

MapStruct官方文档

  1. MapStruct是一个Java注释处理器,用于生成类型安全的bean映射类,它基于约定优于配置方法,极大地简化了 Java bean
    类型之间映射的实现。
  2. 您所要做的就是定义一个mapper接口,该接口声明任何所需的映射方法。在编译期间,MapStruct将生成此接口的实现。此实现使用普通的Java方法调用来在源对象和目标对象之间进行映射,即没有反射或类似。
  3. 与手工编写映射代码相比,MapStruct通过生成繁琐且易于编写的代码来节省时间。遵循约定优于配置方法,MapStruct使用合理的默认值,但在配置或实现特殊行为时会采取措施。
  4. 与动态映射框架相比,MapStruct具有以下优势:
  • 通过使用普通方法调用而不是反射来快速执行

  • 编译时类型安全:只能映射相互映射的对象和属性,不会将订单实体意外映射到客户DTO等。

  • 在构建时清除错误报告,如果

    • 映射不完整(并非所有目标属性都已映射)
    • 映射不正确(找不到合适的映射方法或类型转换)

2、应用设置

2.1 Maven依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.siayou</groupId><artifactId>mapstruct-demo</artifactId><version>1.0-SNAPSHOT</version><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target><org.mapstruct.version>1.4.1.Final</org.mapstruct.version><org.projectlombok.version>1.18.12</org.projectlombok.version></properties><dependencies><dependency><groupId>org.mapstruct</groupId><artifactId>mapstruct</artifactId><version>${org.mapstruct.version}</version></dependency><!-- lombok dependencies should not end up on classpath --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${org.projectlombok.version}</version><scope>provided</scope></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>1.8</source><target>1.8</target><annotationProcessorPaths><path><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${org.projectlombok.version}</version></path><path><groupId>org.mapstruct</groupId><artifactId>mapstruct-processor</artifactId><version>${org.mapstruct.version}</version></path></annotationProcessorPaths></configuration></plugin></plugins></build>
</project>

3、功能实战

3.1 常用注解

  • @Mapper 标记这个接口作为一个映射接口,并且是编译时 MapStruct 处理器的入口
  • @Mapping 解决源对象和目标对象中,属性名字不同的情况
  • @Mappings 当存在多个 @Mapping 需要配置;可以通过 @Mappings 批量指定
  • Mappers.getMapper Mapper 的 class 获取自动生成的实现对象,从而让客户端可以访问 Mapper 接口的实现

3.2 基本映射

3.2.1 定义映射器的Java接口
@Mapper
public interface StudentMapper {StudentMapper INSTANCE = Mappers.getMapper(StudentMapper.class);//mapper可以进行字段映射,改变字段类型,指定格式化的方式,包括一些日期的默认处理。//无论date转string,还是string转date,都是用dateFormat@Mapping(source = "gender.name", target = "gender")@Mapping(source = "birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss")StudentVO student2StudentVO(Student student);
}
// @Data 在编译时会自动添加 Getter、Setter、equals、canEqual、hasCode、toString 等方法,高效且代码非常简洁。
// @Builder 可代替需要的很多构造函数,解决了某个类有很多构造函数的情况。
// @AllArgsConstructor 在编译时会自动添加一个含有所有已声明字段的构造函数,不必再手动编写含有所有已声明字段的构造函数。
// @NoArgsConstructor 在编译时会自动添加一个无参的构造函数,不必再手动编写无参构造函数。
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Student {//姓名private String name;//年龄private int age;//性别private GenderEnum gender;//身高private Double height;//生日private Date birthday;
}@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class StudentVO {//姓名private String name;//年龄private int age;//性别private String gender;//身高private Double height;//生日private String birthday;
}public enum GenderEnum {Male("1", "男"),Female("0", "女");private String code;private String name;public String getCode() {return this.code;}public String getName() {return this.name;}GenderEnum(String code, String name) {this.code = code;this.name = name;}
}
3.2.2 测试验证
    public static void main(String[] args) {Student student = Student.builder().name("张三").age(16).gender(GenderEnum.Male).height(174.3).birthday(new Date()).build();System.out.println(student);StudentVO studentVO = StudentMapper.INSTANCE.student2StudentVO(student);System.out.println(studentVO);}//测试结果
Student(name=张三, age=16, gender=Male, height=174.3, birthday=Fri Sep 22 16:22:38 CST 2023)
StudentVO(name=张三, age=16, gender=, height=174.3, birthday=2023-09-22 16:22:38)

3.3 参数引用映射

3.3.1 定义映射器的Java接口
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class StudentVO {//姓名private String name;//年龄private int age;//性别private String gender;//身高private Double height;//生日private String birthday;private ExtendDto extendDto;
}@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Student {//姓名private String name;//年龄private int age;//性别private GenderEnum gender;//身高private Double height;//生日private Date birthday;private ExtendDto extendDto;
}@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ExtendDto {//邮箱private String email;//地址private String address;//电话private String phone;
}@Mapper
public interface StudentMapper {@Mapping(source = "student.birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss")@Mapping(source = "email", target = "extendDto.email")StudentVO studentTwoStudentVO(Student student,String email);
}
3.3.2 测试验证
public static void main(String[] args) {Student student = Student.builder().name("李四").age(16).gender(GenderEnum.Male).height(174.3).birthday(new Date()).build();System.out.println(student);StudentVO studentVO = StudentMapper.INSTANCE.studentTwoStudentVO(student,"dmjxsy@126.com");System.out.println(studentVO);}//测试结果
Student(name=李四, age=16, gender=Male, height=174.3, birthday=Thu Sep 28 15:12:36 CST 2023, extendDto=null)
StudentVO(name=李四, age=16, gender=Male, height=174.3, birthday=2023-09-28 15:12:36, extendDto=ExtendDto(email=dmjxsy@126.com, address=null, phone=null))

3.4 多对象参数映射

3.4.1 定义映射器的Java接口
    @Mapping(source = "student.birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss")@Mapping(source = "extendDto", target = "extendDto")StudentVO studentMapStudentVO(Student student,ExtendDto extendDto);
3.4.2 测试验证
    public static void main(String[] args) {Student student = Student.builder().name("李四").age(16).gender(GenderEnum.Male).height(174.3).birthday(new Date()).build();ExtendDto extendDto = ExtendDto.builder().email("dmjxsy@126.com").phone("119").address("陕西").build();System.out.println(student);System.out.println(extendDto);StudentVO studentVO = StudentMapper.INSTANCE.studentMapStudentVO(student,extendDto);System.out.println(studentVO);
}//测试结果
Student(name=李四, age=16, gender=Male, height=174.3, birthday=Thu Sep 28 15:24:18 CST 2023, extendDto=null)
ExtendDto(email=dmjxsy@126.com, address=陕西, phone=119)
StudentVO(name=李四, age=16, gender=Male, height=174.3, birthday=2023-09-28 15:24:18, extendDto=ExtendDto(email=dmjxsy@126.com, address=陕西, phone=119))}
3.4.3 注意点

当配置了参数时,在配置对象属性关系映射时,也要显示的指明对象参数的名称。如@Mapping(source = “student.birthday”, target = “birthday”) 就显示指明了 source = “student.birthday” 。

3.5 嵌套映射

3.5.1 定义映射器的Java接口
    @Mapping(source = "student.birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss")@Mapping(source = "extendDto", target = ".")StudentVO studentMapStudentVO(Student student);
3.5.2 测试验证
    public static void main(String[] args) {Student student = Student.builder().name("李四").age(16).gender(GenderEnum.Male).height(174.3).birthday(new Date()).extendDto( ExtendDto.builder().email("dmjxsy@126.com").phone("110").address("陕西").build()).build();System.out.println(student);StudentVO studentVO = StudentMapper.INSTANCE.studentMapStudentVO(student);System.out.println(studentVO);}
//测试结果
Student(name=李四, age=16, gender=Male, height=174.3, birthday=Thu Sep 28 15:31:14 CST 2023, extendDto=ExtendDto(email=dmjxsy@126.com, address=陕西, phone=110))
StudentVO(name=李四, age=16, gender=Male, height=174.3, birthday=2023-09-28 15:31:14, extendDto=ExtendDto(email=dmjxsy@126.com, address=陕西, phone=110))
3.5.3 注意点

使用 “ . ” ,将一个嵌套的bean的值合并到一个扁平化的对象中。

3.6 对象更新

3.6.1 定义映射器的Java接口
    @Mapping(source = "student.birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss")@Mapping(source = "extendDto", target = ".")
//    @Mapping(source = "name",target = "name",  ignore = true)void updateStudent(Student student,@MappingTarget StudentVO studentVO);@Mapping(source = "student.birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss")@Mapping(source = "extendDto", target = ".")@Mapping(source = "name",target = "name",  ignore = true)void updateStudent(Student student,@MappingTarget StudentVO studentVO);
3.6.2 测试验证
public static void main(String[] args) {Student student = Student.builder().name("李四").age(16).gender(GenderEnum.Male).height(174.3).birthday(new Date()).extendDto( ExtendDto.builder().email("dmjxsy@126.com").phone("110").address("陕西").build()).build();StudentVO studentVO = StudentVO.builder().name("王五").age(20).height(204.3).birthday("2020-01-01 12:11:11").extendDto( ExtendDto.builder().email("dmjxsy@163.com").phone("110110119").address("陕西西安").build()).build();System.out.println("更新前 student:"+student.toString());System.out.println("更新前 studentVO:"+studentVO.toString());StudentMapper.INSTANCE.updateStudent(student,studentVO);System.out.println("更新后 student:"+student.toString());System.out.println("更新后 studentVO:"+studentVO.toString());}
//测试结果
更新前 :Student(name=李四, age=16, gender=Male, height=174.3, birthday=Thu Sep 28 15:56:35 CST 2023, extendDto=ExtendDto(email=dmjxsy@126.com, address=陕西, phone=110))
更新前 :StudentVO(name=王五, age=20, gender=null, height=204.3, birthday=2020-01-01 12:11:11, extendDto=ExtendDto(email=dmjxsy@163.com, address=陕西西安, phone=110110119))
更新后 :Student(name=李四, age=16, gender=Male, height=174.3, birthday=Thu Sep 28 15:56:35 CST 2023, extendDto=ExtendDto(email=dmjxsy@126.com, address=陕西, phone=110))
更新后 :StudentVO(name=李四, age=16, gender=Male, height=174.3, birthday=2023-09-28 15:56:35, extendDto=ExtendDto(email=dmjxsy@126.com, address=陕西, phone=110))
//添加 @Mapping(source = "name",target = "name",  ignore = true)
更新前 :Student(name=李四, age=16, gender=Male, height=174.3, birthday=Thu Sep 28 15:57:39 CST 2023, extendDto=ExtendDto(email=dmjxsy@126.com, address=陕西, phone=110))
更新前 :StudentVO(name=王五, age=20, gender=null, height=204.3, birthday=2020-01-01 12:11:11, extendDto=ExtendDto(email=dmjxsy@163.com, address=陕西西安, phone=110110119))
更新后 :Student(name=李四, age=16, gender=Male, height=174.3, birthday=Thu Sep 28 15:57:39 CST 2023, extendDto=ExtendDto(email=dmjxsy@126.com, address=陕西, phone=110))
更新后 :StudentVO(name=王五, age=16, gender=Male, height=174.3, birthday=2023-09-28 15:57:39, extendDto=ExtendDto(email=dmjxsy@126.com, address=陕西, phone=110))
3.6.3 注意点

@MappingTarget 使用改注解标记目标对象我们就可以更新该对象的值。如果想不更新某个值,可以给加一个ignore = true的标签来忽略。

4、性能比较

4.1 Apache BeanUtils 与 MapStruct比较

 public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {for (int i = 0; i < 10; i++) {Long start = System.currentTimeMillis();for (int i1 = 0; i1 < 1000000; i1++) {Student student = Student.builder().name("小明").age(6).gender(GenderEnum.Male).height(121.1).birthday(new Date()).build();StudentVO studentVO = new StudentVO();org.apache.commons.beanutils.BeanUtils.copyProperties(studentVO, student);}System.out.println("org.apache.commons.beanutils.BeanUtils第"+ i +"次执行---100W次转换耗时:" + (System.currentTimeMillis() - start));Long start2 = System.currentTimeMillis();for (int i1 = 0; i1 < 1000000; i1++) {Student student = Student.builder().name("小明").age(6).gender(GenderEnum.Male).height(121.1).birthday(new Date()).build();StudentMapper.INSTANCE.student2StudentVO(student);}System.out.println("MapStruct第"+ i +"次执行-----100W次转换耗时:" + (System.currentTimeMillis() - start2));}}
//测试结果
org.apache.commons.beanutils.BeanUtils0次执行---100W次转换耗时:11854
MapStruct0次执行-----100W次转换耗时:1981
org.apache.commons.beanutils.BeanUtils1次执行---100W次转换耗时:10828
MapStruct1次执行-----100W次转换耗时:2080
org.apache.commons.beanutils.BeanUtils2次执行---100W次转换耗时:9894
MapStruct2次执行-----100W次转换耗时:1891
org.apache.commons.beanutils.BeanUtils3次执行---100W次转换耗时:9543
MapStruct3次执行-----100W次转换耗时:1735
org.apache.commons.beanutils.BeanUtils4次执行---100W次转换耗时:6862
MapStruct4次执行-----100W次转换耗时:1958

4.2 Hutool BeanUtil与 MapStruct比较

public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {for (int i = 0; i < 5; i++) {Long start = System.currentTimeMillis();for (int i1 = 0; i1 < 1000000; i1++) {Student student = Student.builder().name("小明").age(6).gender(GenderEnum.Male).height(121.1).birthday(new Date()).build();StudentVO studentVO = new StudentVO();cn.hutool.core.bean.BeanUtil.copyProperties(studentVO,student,true);}System.out.println("cn.hutool.core.bean.BeanUtil第"+ i +"次执行---100W次转换耗时:" + (System.currentTimeMillis() - start));Long start2 = System.currentTimeMillis();for (int i1 = 0; i1 < 1000000; i1++) {Student student = Student.builder().name("小明").age(6).gender(GenderEnum.Male).height(121.1).birthday(new Date()).build();StudentMapper.INSTANCE.student2StudentVO(student);}System.out.println("MapStruct第"+ i +"次执行-----100W次转换耗时:" + (System.currentTimeMillis() - start2));}}
//测试结果
cn.hutool.core.bean.BeanUtil0次执行---100W次转换耗时:7169
MapStruct0次执行-----100W次转换耗时:2538
cn.hutool.core.bean.BeanUtil1次执行---100W次转换耗时:4797
MapStruct1次执行-----100W次转换耗时:1707
cn.hutool.core.bean.BeanUtil2次执行---100W次转换耗时:5582
MapStruct2次执行-----100W次转换耗时:1505
cn.hutool.core.bean.BeanUtil3次执行---100W次转换耗时:4906
MapStruct3次执行-----100W次转换耗时:1322
cn.hutool.core.bean.BeanUtil4次执行---100W次转换耗时:3789
MapStruct4次执行-----100W次转换耗时:1635

4.3 Spring BeanUtils 与 MapStruct比较

    public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {for (int i = 0; i < 5; i++) {Long start = System.currentTimeMillis();for (int i1 = 0; i1 < 1000000; i1++) {Student student = Student.builder().name("小明").age(6).gender(GenderEnum.Male).height(121.1).birthday(new Date()).build();StudentVO studentVO = new StudentVO();org.springframework.beans.BeanUtils.copyProperties(studentVO, student);}System.out.println("org.springframework.beans.BeanUtils第"+ i +"次执行---100W次转换耗时:" + (System.currentTimeMillis() - start));Long start2 = System.currentTimeMillis();for (int i1 = 0; i1 < 1000000; i1++) {Student student = Student.builder().name("小明").age(6).gender(GenderEnum.Male).height(121.1).birthday(new Date()).build();StudentMapper.INSTANCE.student2StudentVO(student);}System.out.println("MapStruct第"+ i +"次执行-----100W次转换耗时:" + (System.currentTimeMillis() - start2));}}
//测试结果
org.springframework.beans.BeanUtils0次执行---100W次转换耗时:1156
MapStruct0次执行-----100W次转换耗时:3376
org.springframework.beans.BeanUtils1次执行---100W次转换耗时:290
MapStruct1次执行-----100W次转换耗时:1367
org.springframework.beans.BeanUtils2次执行---100W次转换耗时:506
MapStruct2次执行-----100W次转换耗时:1586
org.springframework.beans.BeanUtils3次执行---100W次转换耗时:318
MapStruct3次执行-----100W次转换耗时:1319
org.springframework.beans.BeanUtils4次执行---100W次转换耗时:304
MapStruct4次执行-----100W次转换耗时:1226

4.4 Cglib BeanCopier 与 MapStruct比较

 public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {for (int i = 0; i < 5; i++) {Long start = System.currentTimeMillis();for (int i1 = 0; i1 < 1000000; i1++) {Student student = Student.builder().name("小明").age(6).gender(GenderEnum.Male).height(121.1).birthday(new Date()).build();StudentVO studentVO = new StudentVO();org.springframework.cglib.beans.BeanCopier.create(StudentVO.class, Student.class, false);}System.out.println("org.springframework.cglib.beans.BeanCopier第"+ i +"次执行---100W次转换耗时:" + (System.currentTimeMillis() - start));Long start2 = System.currentTimeMillis();for (int i1 = 0; i1 < 1000000; i1++) {Student student = Student.builder().name("小明").age(6).gender(GenderEnum.Male).height(121.1).birthday(new Date()).build();StudentMapper.INSTANCE.student2StudentVO(student);}System.out.println("MapStruct第"+ i +"次执行-----100W次转换耗时:" + (System.currentTimeMillis() - start2));}}//测试结果
org.springframework.cglib.beans.BeanCopier0次执行---100W次转换耗时:725
MapStruct0次执行-----100W次转换耗时:4524
org.springframework.cglib.beans.BeanCopier1次执行---100W次转换耗时:210
MapStruct1次执行-----100W次转换耗时:1663
org.springframework.cglib.beans.BeanCopier2次执行---100W次转换耗时:72
MapStruct2次执行-----100W次转换耗时:1446
org.springframework.cglib.beans.BeanCopier3次执行---100W次转换耗时:80
MapStruct3次执行-----100W次转换耗时:1482
org.springframework.cglib.beans.BeanCopier4次执行---100W次转换耗时:84
MapStruct4次执行-----100W次转换耗时:1441

4.4 性能对比结果(5次平均值)

工具类执行1000执行1w执行10w执行100w
Apache BeanUtils103.2323.31105.87227.8
Hutool BeanUtil111249.2925.44420.6
Spring BeanUtils8093.4206.4728.6
Cglib BeanCopier86.4103.8103.8263
MapStruct53.6137.8447.82672.2

相关文章:

MapStruct应用实战及BeanUtils性能比较

目录 1、MapStruct介绍2、应用设置2.1 Maven依赖 3、功能实战3.1 常用注解3.2 基本映射3.2.1 定义映射器的Java接口3.2.2 测试验证 3.3 参数引用映射3.3.1 定义映射器的Java接口3.3.2 测试验证 3.4 多对象参数映射3.4.1 定义映射器的Java接口3.4.2 测试验证3.4.3 注意点 3.5 嵌…...

ISP技术概述

原本或许是为了对冲手机系统和APP设计无力感而诞生的拍照功能,现今却成为了众手机厂家除背部设计外为数不多可“卷”的地方,自拍、全景、夜景、小视频等旺盛的需求让这一技术的江湖地位迅速变化。对圈内人士而言,这一波变化带来的后摄、双摄、多摄、暗光、防抖、广角、长焦、…...

CSDN: ABTest流量分层分桶机制

在互联网行业&#xff0c;无论是构建搜索推荐系统&#xff0c;还是智能营销等场景&#xff0c;都是围绕用户进行不同的实验&#xff0c;从各项指标上观察用户对不同交互、流程、策略、算法等反馈&#xff0c;进而对产品进行迭代改进。 本文的goal&#xff1a;在进行了模型的线下…...

【小余送书第一期】《数据要素安全流通》参与活动,即有机会中奖哦!!

目录 1、背景介绍 2、本书编撰背景 3、本书亮点 4、本书主要内容 5、活动须知 1、背景介绍 随着大数据、云计算、人工智能等新兴技术的迅猛发展&#xff0c;数据已经成为我国经济社会发展的五大生产要素之一&#xff0c;《网络安全法》《个人信息保护法》《数据安全法》的…...

蓝牙核心规范(V5.4)10.7-BLE 入门笔记之L2CAP

1.概述 ATT属性用于两个设备,一个扮演客户端的角色,另一个扮演服务器的角色。服务器公开一系列称为属性的复合数据项。这些属性由服务器按索引列表组织在称为属性表的列表中。 每个属性包含一个句柄、一个通用唯一标识符(UUID)、一个值和一组权限。 句柄是一个唯一的索引…...

VUE之正则表达式全集整理

一、正则表达式的基本语法 var expression /pattern(模式)/flags(标识符); 二、如何创建正则表达式 1.字面量创建 代码如下&#xff1a; //匹配字符串中所有“at”的实例 var e /at/g; //匹配第一个“bat”或“cat”,不区分大小写 var e /[bc]at/i; 2.RegExp构造函数创…...

Python 中的字符串基础与应用

在Python中&#xff0c;字符串可以用单引号或双引号括起来。‘hello’ 与 “hello” 是相同的。您可以使用print()函数显示字符串文字&#xff1a; 示例&#xff1a; print("Hello") print(Hello)将字符串分配给变量是通过变量名后跟等号和字符串完成的&#xff1a…...

C++:如何实现数组元素逆置?多种方法

方法1&#xff1a;使用额外的数组 这是一种比较简单的方法&#xff0c;它创建一个额外的数组来存储逆置后的元素&#xff0c;然后将其复制回原始数组。 #include <iostream>void reverseArray(int arr[], int size) {int reversed[size];for (int i 0; i < size; i)…...

php框架thinkPHP6的安装教程

1&#xff0c;composer官网下载最新版本 composerhttps://getcomposer.org/download/ 2&#xff0c;双击下载后的运行文件&#xff0c;一直点击next就行了 上面这个路径根据自己安装的php版本位置选择&#xff08;没有的可以下载一个phpstudy&#xff09;&#xff0c;最后需要…...

PTA程序辅助实验平台——2023年软件设计综合实践_3(分支与循环)

第一题&#xff1a;7-1 印第安男孩 - C/C 分支与循环 朵拉编程的时候也想顺便练习英语。她编程从键盘读入一个整数n&#xff0c;如果n值为0或者1&#xff0c;向屏幕输出“0 indian boy.”或“1 indian boy.”&#xff1b;如果n大于1&#xff0c;比如9&#xff0c;则输出“9 in…...

【C语言数据结构】线性表-链式存储-单链表

线性表-链式存储-单链表 代码实现 代码实现 #include<stdio.h> #include<stdlib.h> #include<stdbool.h>//定义元素数据类型 #define ElemType int//定义结点结构体 typedef struct LNode {//数据域&#xff0c;说白了就是存放当前节点的数据的。ElemType d…...

tp8 Editor.md

Editor.md - 开源在线 Markdown 编辑器 放于public文件夹下 html代码&#xff1a; <div class"layui-col-md12" id"content"><textarea name"content" placeholder"详情" class"layui-textarea">{notempty nam…...

LM小型可编程控制器软件(基于CoDeSys)笔记三十一:保持变量和非保持变量

所谓变量&#xff0c;就是用字母、数字和下划线组成的一个标识符。 按照数据类型的不同&#xff0c;变量可以分为标准类型和用户自定义类型。其中标准类型包括布尔型 &#xff08; BOOL &#xff09;、整型&#xff08; INT &#xff09;、实型&#xff08; REAL &#xff09…...

「C++之STL」关于在模拟实现STL容器中的深浅拷贝问题

文章目录 前言杨辉三角深浅拷贝问题模拟实现的vector对题目杨辉三角引发的程序崩溃原因解决办法 前言 在学习STL容器中,不仅需要学会容器的使用,同时也需要了解容器的大体框架以及各个函数的模拟实现才能更好的去了解这个容器; 杨辉三角 在LeetCode中有一道这样的题目,给定一…...

文件内容显示

目录 1.浏览普通文件 1.1. 文件内容查看 1.1.1. cat 命令 例&#xff1a; 1.1.2 扩展tac命令&#xff1a; 1.1.3. more 命令 1.1.4. less命令 1.1.5. head命令 1.1.6. tail命令 1.2. 文件属性信息查看 1.2.1. file 命令 1.2.2. stat 命令 2. 文件内容过滤…...

Milvus+Attu

Milvus 1.下载 https://github.com/milvus-io/milvus/releases/wget https://github.com/milvus-io/milvus/releases/download/v2.3.0/milvus-standalone-docker-compose.yml下载milvus-standalone-docker-compose version: 3.5services:etcd:container_name: milvus-etcdim…...

LeetCode算法二叉树—226. 翻转二叉树

目录 226. 翻转二叉树 代码&#xff1a; 运行结果&#xff1a; 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a; 输入&#xff1a;root [4,2,7,1,3,6,9] 输出&#xff1a;[4,7,2,9,6,3,1]示例 2&#xff1a; 输入…...

AI项目十:Swin Transformer目标检测环境搭建

若该文为原创文章&#xff0c;转载请注明原文出处。 Swin Transformer是做什么的这里不做介绍&#xff0c;主要是记录下学习的全过程&#xff0c;Swin Transformer在搭建和训练的过程中&#xff0c;折腾了很久&#xff0c;主要是在折腾环境。 一、AutoDL租用实例 个人没有GP…...

【IPC 通信】信号处理接口 Signal API(5)

收发信号思想是 Linux 程序设计特性之一&#xff0c;一个信号可以认为是一种软中断&#xff0c;通过用来向进程通知异步事件。 本文讲述的 信号处理内容源自 Linux man。本文主要对各 API 进行详细介绍&#xff0c;从而更好的理解信号编程。 kill(2) 遵循 POSIX.1 - 2008 1.库 …...

Arduino PLC IDE

Arduino PLC IDE MCU单片机进入全新的PLC领域概述需要的硬件和软件下一步操作1. Arduino PLC IDE Tool Setup2. Arduino PLC IDE Setup3. Project Setup4. Download the Runtime5. Connect to the Device6. License Activation with Product Key (Portenta Machine Control) 结…...

记录使用iText7查找PDF内容关键字坐标,加盖电子签名、印章

一、前言 项目以前签字都是由C端那边进行合成操作&#xff0c;最近项目要求把那块功能&#xff0c;由后端进行实现&#xff0c;其中包含坐标、关键字、任意位置进行签字操作&#xff0c;坐标是最容易实现的&#xff0c;曾经也写过类似的功能在&#xff08;添加图片印章到PDF&a…...

Java8实战-总结37

Java8实战-总结37 默认方法不断演进的 API初始版本的 API第二版 API 默认方法 传统上&#xff0c;Java程序的接口是将相关方法按照约定组合到一起的方式。实现接口的类必须为接口中定义的每个方法提供一个实现&#xff0c;或者从父类中继承它的实现。但是&#xff0c;一旦类库…...

【超详细】前段开发之详细的Vue3入门教程,特别适合小白系统学习,入门到熟练使用Vue看这一篇就够了!

前言&#xff1a; 这篇文章更加侧重的是Vue3不同于Vue2的知识点&#xff0c;如果学习Vue2请看下面这篇文章 Vue2详细系统入门教程 11.2 Vue3 声明&#xff1a;图片资源来自于黑马程序员公开学习资料 本人在学习当中&#xff0c;详细整理了笔记&#xff0c;供大家参考学习 1…...

【深度学习】ONNX模型多线程快速部署【基础】

【深度学习】ONNX模型CPU多线程快速部署【基础】 提示:博主取舍了很多大佬的博文并亲测有效,分享笔记邀大家共同学习讨论 文章目录 【深度学习】ONNX模型CPU多线程快速部署【基础】前言搭建打包环境python多线程并发简单教程基本教程ONNX模型多线程并发 打包成可执行文件总结 前…...

Python 同、异步HTTP客户端封装:性能与简洁性的较量

一、前言 引入异步编程趋势&#xff1a;Python的异步编程正变得越来越流行。在过去&#xff0c;同步的HTTP请求已经不足以满足对性能的要求。异步HTTP客户端库的流行&#xff1a;目前&#xff0c;有许多第三方库已经实现了异步HTTP客户端&#xff0c;如aiohttp和httpx等。然而…...

无代码赋能数字化,云表搭桥铺路链接“数据孤岛”

什么是信息孤岛 企业数字化转型过程中&#xff0c;信息孤岛是一个突出的问题。这种情况发生的原因是&#xff0c;企业内部使用了多种应用软件&#xff0c;时间一长&#xff0c;员工在不同的系统中积累了大量的企业数据资产。然而&#xff0c;由于这些系统之间的数据无法互通&am…...

无需公网IP,实现公网SSH远程登录MacOS【内网穿透】

目录 前言 1. macOS打开远程登录 2. 局域网内测试ssh远程 3. 公网ssh远程连接macOS 3.1 macOS安装配置cpolar 3.2 获取ssh隧道公网地址 3.3 测试公网ssh远程连接macOS 4. 配置公网固定TCP地址 4.1 保留一个固定TCP端口地址 4.2 配置固定TCP端口地址 5. 使用固定TCP端…...

网络爬虫学习笔记 1 HTTP基本原理

HTTP原理 ~~~~~ HTTP&#xff08;Hyper Text Transfer Protocol&#xff0c;超文本传输协议&#xff09;是一种使用最为广泛的网络请求方式&#xff0c;常见于在浏览器输入一个地址。 1. URI和URL URL&#xff08;Universal Resource Locator&#xff0c;统一资源定位器&…...

113. 路径总和ii

力扣题目链接(opens new window) 给定一个二叉树和一个目标和&#xff0c;找到所有从根节点到叶子节点路径总和等于给定目标和的路径。 说明: 叶子节点是指没有子节点的节点。 示例: 给定如下二叉树&#xff0c;以及目标和 sum 22&#xff0c; 在路径总和题目的基础上&…...

百度APP iOS端包体积50M优化实践(六)无用方法清理

一、前言 百度APP包体积经过一期优化&#xff0c;如无用资源清理&#xff0c;无用类下线&#xff0c;Xcode编译相关优化&#xff0c;体积已经有了明显的减少。但是优化后APP包体积在iPhone11上仍有350M的空间占用。与此同时百度APP作为百度的旗舰APP&#xff0c;业务迭代非常多…...

湖北自适应网站建设报价/广州专门做网站

2019独角兽企业重金招聘Python工程师标准>>> 本文纯粹是个整理。 以下代码和图片来自C 11右值引用。 class CMyString { public:// 构造函数CMyString(const char *pszSrc NULL){cout << "CMyString(const char *pszSrc NULL)" << endl;if …...

湖北宜昌网络科技有限公司/公司百度官网优化

内存是稀缺的资源&#xff0c;哪怕内存一块钱一条&#xff01;如果在编程中使用不当&#xff0c;再大的内存也会耗光。一、认识Java的自动垃圾回收垃圾回收是Java语言的一大特性&#xff0c;方便了编程&#xff0c;是以消耗性能为代价的。而垃圾在这里只无用的对象。而C是需要程…...

网站建设的关键点/seo免费入门教程

产品合格证标签是产品生产出售过程中的一个重要的标牌&#xff0c;产品合格证的外观有很多种&#xff0c;方形合格证&#xff0c;圆形合格证&#xff0c;三角形合格证&#xff0c;那么这些各种各样的合格证标签是怎么制作出来的呢&#xff1f;下面以三角形合格证为例子教大家如…...

有没有专门做av字幕的网站/北京网络营销咨询公司

本系列意在记录Windwos线程的相关知识点&#xff0c;包括线程基础、线程调度、线程同步、TLS、线程池等 本篇介绍与内核对象同步相关的Event对象和Mutex对象 AutoResetEvent和ManualResetEvent 同步事件有两种&#xff1a;AutoResetEvent和 ManualResetEvent。主要用户线程之间…...

无锡哪里做网站/seo专员是什么

胆大心细做事&#xff0c;低调谦虚做人&#xff01;转载于:https://blog.51cto.com/09112012/2051790...

苏南建设集团网站/优化设计单元测试卷答案

摘要 本篇经验将和大家介绍Windows下安装和部署RabbitMQ消息队列服务器&#xff0c;希望对大家的工作和学习有所帮助&#xff01; 目录 一、Erlang语言环境的搭建 二、RabbitMQ服务环境的搭建 三、RabbitMQ服务Web管理工具 一、Erlang语言环境的搭建 RabbitMQ开源消息队列服务是…...