【JAVA基础】JAVA类的拷贝使用示例

news2024/11/18 4:22:41

文章目录

    • 一、框架介绍
    • 二、性能对比
    • 三、易用性对比
    • 四、使用示例
      • (一)Apache Commons BeanUtils 使用例子
        • 1、第一个例子:两个对象属性个数和名称一样,复制过程
        • 2、第二个例子:属性个数和名称不一样,复制过程
      • (二) MapStruct使用示例
    • 五、最终总结:

在这里插入图片描述

BeanUtils.copyProperties是Apache Commons
BeanUtils库中的一个方法,用于将一个Java对象的属性值复制到另一个Java对象中。这个方法简化了对象之间属性复制的过程,减少了手动编写逐个属性赋值的工作量,使得代码更加简洁、易于维护。

在Java开发中,我们经常需要将一个JavaBean对象的属性值复制到另一个JavaBean对象中,尤其是在数据转换、DTO(Data Transfer Object)转换等场景中。为了解决这个问题,本文将对这些框架进行性能对比,帮助开发者选择最适合自己项目的工具。

一、框架介绍

  • 1 、Apache Commons BeanUtils
    Apache Commons BeanUtils是一个用于操作JavaBean的工具类库,它提供了丰富的API来操作JavaBean的属性,包括属性拷贝。

  • 2 、Spring BeanUtils
    Spring框架自带的BeanUtils类也提供了属性拷贝的功能,通常与Spring框架一起使用。

  • 3 、ModelMapper
    ModelMapper是一个智能的对象映射库,它可以自动将一种类型的对象转换为另一种类型的对象,包括Bean的属性拷贝。

  • 4 、MapStruct
    MapStruct是一个基于注解的代码生成器,用于在Java Bean或POJO(Plain Old Java Object)之间进行映射。它生成的代码性能较高,但需要预先生成映射类。

二、性能对比

为了比较各框架的性能,我们进行了以下测试:

测试数据:创建一个包含10个属性的简单JavaBean对象。
测试方法:分别使用上述四个框架将源对象的属性值拷贝到目标对象中,记录每次操作所消耗的时间。
测试次数:对每个框架进行100万次测试,以减小误差。
测试结果如下:
在这里插入图片描述
从测试结果来看,MapStruct的性能最好,其次是Apache Commons BeanUtils和Spring BeanUtils,最后是ModelMapper。需要注意的是,这只是一个简单的测试,实际性能可能会因为具体的使用场景、对象属性数量、属性类型等因素而有所不同。

三、易用性对比

除了性能之外,易用性也是选择Bean属性拷贝工具类框架时需要考虑的因素。以下是各框架的易用性评价:

Apache Commons BeanUtils:API相对简单,但功能较为基础,对于复杂的映射场景可能需要手动处理。

Spring BeanUtils:与Spring框架集成紧密,适合在Spring项目中使用。但同样,对于复杂的映射场景可能需要额外处理。

ModelMapper:提供了丰富的配置选项,可以自动处理大部分映射场景。但在处理复杂类型或特殊需求时可能需要自定义配置。

MapStruct:需要预先生成映射类,对于大型项目来说可能需要花费一定的时间。但生成的代码性能较高,且支持自定义映射逻辑。

四、使用示例

(一)Apache Commons BeanUtils 使用例子

1、第一个例子:两个对象属性个数和名称一样,复制过程

在这个例子中,我们有两个类User和Person,它们的属性个数和名称都是一样的。我们可以使用BeanUtils.copyProperties方法将User对象的属性值复制到Person对象中。

import org.apache.commons.beanutils.BeanUtils;  
  
@Data // 假设使用了Lombok的@Data注解来自动生成getter和setter  
public class User {  
    private String id;  
    private String name;  
    private String age; // 注意:这里使用String类型作为示例,实际中年龄可能用int或Integer更合适  
}  
  
@Data // 假设使用了Lombok的@Data注解来自动生成getter和setter  
public class Person {  
    private String id;  
    private String name;  
    private String age; // 同样使用String类型作为示例  
}  
  
public class Test {  
    public static void main(String[] args) {  
        User user = new User();  
        user.setId("1");  
        user.setName("John Doe");  
        user.setAge("30"); // 示例中使用String类型  
  
        Person person = new Person();  
        try {  
            BeanUtils.copyProperties(person, user); // 注意:这里源对象在前,目标对象在后  
            // 输出验证  
            System.out.println(person); // 输出:Person(id=1, name=John Doe, age=30)  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
}  
  
// 注意:在实际使用中,如果源对象和目标对象的属性类型不一致但可以进行转换(如String到Integer),  
// 则BeanUtils会尝试进行类型转换。如果转换失败,将抛出异常。

**注意:**在上面的例子中,BeanUtils.copyProperties方法的参数顺序是目标对象在前,源对象在后,这与某些人的直觉可能相反。然而,这是BeanUtils库的设计方式。

2、第二个例子:属性个数和名称不一样,复制过程

当两个对象的属性个数和名称不一样时,BeanUtils.copyProperties方法只会复制那些名称相同且类型兼容的属性。对于名称不同或类型不兼容的属性,它们将不会被复制。

@Data  
public class SourceObject {  
    private String id;  
    private String userName; // 注意:这里属性名为userName  
    private int age; // 使用int类型  
}  
  
@Data  
public class TargetObject {  
    private String id;  
    private String name; // 注意:这里属性名为name  
    private String age; // 使用String类型  
    private String email; // TargetObject特有的属性  
}  
  
public class Test {  
    public static void main(String[] args) {  
        SourceObject source = new SourceObject();  
        source.setId("1");  
        source.setUserName("Jane Doe"); // 注意:这里设置的是userName  
        source.setAge(25); // 使用int类型  
  
        TargetObject target = new TargetObject();  
        try {  
            BeanUtils.copyProperties(source, target); // 尝试复制  
            // 输出验证  
            System.out.println(target); // 输出:TargetObject(id=1, name=null, age=null, email=null)  
            // 注意:由于name和userName名称不同,age类型不同,所以这些属性没有被复制  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
}

Apache Commons BeanUtils 处理属性名称不一致的情况:
如果需要在属性名称不一致的情况下进行属性复制,可以考虑以下几种方法:

  • 1、手动设置:直接通过目标对象的setter方法手动设置属性值。
    -2、使用Map作为中间对象:先将源对象的属性值复制到Map中,然后根据需要调整Map中的键名(即属性名),最后将Map中的值复制到目标对象中。
  • 3、自定义复制逻辑:编写自定义的方法来实现复杂的属性复制逻辑。
  • 4、使用Spring的BeanUtils或其他库:Spring的BeanUtils提供了更灵活的复制选项,包括忽略某些属性、处理嵌套对象等。但请注意,Spring的BeanUtils和Apache Commons BeanUtils是两个不同的库。
    注意:在实际应用中,如果两个对象的属性名称不一致,通常意味着它们在设计上代表了不同的概念或用途,因此可能需要重新考虑是否应该进行属性复制,或者是否应该通过其他方式来实现数据的传递和转换。

(二) MapStruct使用示例

  1. 引入依赖
    首先,你需要在项目的pom.xml文件中引入MapStruct的依赖。以下是一个示例依赖配置(注意版本可能会更新,请根据实际情况选择合适的版本):
<properties>  
    <mapstruct.version>1.5.5.Final</mapstruct.version> <!-- 请根据需要使用最新的稳定版本 -->  
</properties>  
  
<dependencies>  
    <dependency>  
        <groupId>org.mapstruct</groupId>  
        <artifactId>mapstruct</artifactId>  
        <version>${mapstruct.version}</version>  
    </dependency>  
    <dependency>  
        <groupId>org.mapstruct</groupId>  
        <artifactId>mapstruct-processor</artifactId>  
        <version>${mapstruct.version}</version>  
        <scope>provided</scope> <!-- 设置为provided,因为注解处理器在编译时使用 -->  
    </dependency>  
</dependencies>
  1. 定义源类和目标类
    假设你有两个Java Bean类,一个是源类Person,另一个是目标类PersonDto。
public class Person {  
    private String firstName;  
    private String lastName;  
    // getters and setters  
}  
  
public class PersonDto {  
    private String fullName;  
    // getters and setters  
}
  1. 创建Mapper接口
    然后,你需要创建一个Mapper接口,该接口定义了从源类到目标类的映射规则。
import org.mapstruct.Mapper;  
import org.mapstruct.Mapping;  
import org.mapstruct.factory.Mappers;  
  
@Mapper  
public interface PersonMapper {  
  
    PersonMapper INSTANCE = Mappers.getMapper(PersonMapper.class);  
  
    @Mapping(target = "fullName", expression = "java(person.getFirstName() + ' ' + person.getLastName())")  
    PersonDto personToPersonDto(Person person);  
}

在上面的Mapper接口中,@Mapper注解标记了这是一个MapStruct的Mapper接口。@Mapping注解定义了映射规则,其中target属性指定了目标类的属性名,expression属性则是一个Java表达式,用于定义如何从源类的属性计算得到目标类的属性值。

  1. 使用Mapper接口
    最后,你可以在代码中直接使用Mapper接口进行对象转换。
Person person = new Person();  
person.setFirstName("John");  
person.setLastName("Doe");  
  
PersonDto personDto = PersonMapper.INSTANCE.personToPersonDto(person);  
System.out.println(personDto.getFullName()); // 输出: John Doe

在这个例子中,PersonMapper.INSTANCE.personToPersonDto(person)会自动将Person对象转换为PersonDto对象,并且根据@Mapping注解中定义的规则,将Person的firstName和lastName拼接后赋值给PersonDto的fullName属性。

使用注意:
MapStruct通过注解和代码生成的方式,提供了一种简洁、类型安全且高性能的对象转换方法。它特别适用于处理复杂的对象图映射,并且支持多种高级特性,如自定义映射方法、嵌套映射、集合映射等。在实际项目中,合理使用MapStruct可以显著提高开发效率和代码质量。

五、最终总结:

综合性能和易用性两方面的因素,开发者可以根据自己的项目需求选择合适的Bean属性拷贝工具类框架。对于追求极致性能的场景,MapStruct可能是一个不错的选择;而在简单的映射场景中,Apache Commons BeanUtils或Spring BeanUtils可能更加合适。对于需要自动处理复杂映射场景的开发者来说,ModelMapper可能是一个值得考虑的选项。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2166859.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

简易STL实现 | 红黑树的实现

1、原理 红黑树&#xff08;Red-Black Tree&#xff09;是一种自平衡的二叉搜索树 红黑树具有以下特性&#xff0c;这些特性保持了树的平衡&#xff1a; 节点颜色&#xff1a; 每个节点要么是红色&#xff0c;要么是黑色根节点颜色&#xff1a; 根节点是黑色的。叶子节点&…

信息收集---CDN指纹识别

1. 什么是CDN 在渗透测试过程中&#xff0c;经常会碰到网站有CDN的情况。CDN即内容分发网络&#xff0c;主要解决因传输距离和不同运营商节点造成的网络速度性能低下的问题。说的简单点&#xff0c;就是一组在不同运营商之间的对接点上的高速缓存服务器&#xff0c;把用户经常访…

蓝牙技术|蓝牙6.0技术或将实现厘米级精确查找定位功能

蓝牙技术联盟发布蓝牙 6.0 技术规范&#xff0c;引入了一项名为蓝牙“信道探测”的新功能&#xff0c;可以在两个蓝牙 LE 设备之间实现双向测距&#xff0c;有望为电子设备上的“查找”功能带来更精确的定位能力。蓝牙技术联盟表示&#xff0c;这项新技术将为数十亿未来的蓝牙设…

深度学习:调整学习率

目录 前言 一、什么是调整学习率&#xff1f; 二、调整学习率的作用 三、怎么调整学习率 1.有序调整 2.自适应调整 3.自定义调整 4.调整示例 前言 在深度学习中&#xff0c;调整学习率是非常重要的&#xff0c;它对模型的训练效果和收敛速度有显著影响。 一、什么是调整…

前端问答:如何用 JavaScript 让 HTML Canvas全屏显示

哈喽&#xff0c;大家好&#xff01;今天要跟大家分享一个非常实用的小技巧&#xff0c;适合那些正在学习前端开发的朋友们。你是不是也遇到过这样的问题&#xff1a;在制作一些网页小游戏、炫酷的网页动画或者数据可视化时&#xff0c;想让画布&#xff08;Canvas&#xff09;…

Ubuntu24.04 yum安装

安装yum&#xff1a; sudo apt-get install yum 执行报错 E: Package yum has no installation candidate 解决&#xff1a;更换镜像源&#xff0c;找到自己的系统版本&#xff08;如本系统为Ubuntu24.04&#xff09;用vim进行更换&#xff0c;网址&#xff1a; ubuntu | 镜…

26 基于STM32的智能门禁系统(指纹、蓝牙、刷卡、OLED、电机)

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于STM32单片机&#xff0c;六个按键&#xff0c;分别代表指纹、蓝牙、刷卡的正确进门与错误进门&#xff1b; 比如第一个按键按下&#xff0c;表示指纹正确&#xff0c;OLED显示指纹正确&#x…

linux服务器部署filebeat

# 下载filebeat curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.17.23-linux-x86_64.tar.gz # 解压 tar xzvf filebeat-7.17.23-linux-x86_64.tar.gz# 所在位置&#xff08;自定义&#xff09; /opt/filebeat-7.17.23-linux-x86_64/filebeat.ym…

FreeRTOS——任务调度、任务状态

任务调度 调度器就是使用相关的调度算法来决定当前需要执行哪个任务。 FreeRTOS一共支持三种任务调度方式&#xff1a; 抢占式调度&#xff1a;主要是针对优先级不同的任务&#xff0c;每个任务都有一个优先级&#xff0c;优先级高的任务可以抢占优先级低的任务。&#xff08…

word批量裁剪图片,并调整图片大小,不锁定纵横比

在word中有若干图片待处理&#xff0c;裁剪出指定内容&#xff0c;调整成指定大小。如下是待处理的图片&#xff1a; 这时&#xff0c;选择视图&#xff0c;选择宏&#xff0c;查看宏 选择创建宏 添加cut_picture代码如下&#xff0c;其中上、下、左、右裁剪的橡塑尺寸根据自己…

【2】图像视频的加载和显示

文章目录 【2】图像视频的加载和显示一、代码在哪写二、创建和显示窗口&#xff08;一&#xff09;导入OpenCV的包cv2&#xff08;二&#xff09;创建窗口&#xff08;三&#xff09;更改窗口大小 & 显示窗口&#xff08;四&#xff09;等待用户输入补充&#xff1a;ord()函…

24最新ComfyUI搭建使用教程

前言 ComfyUI 是一个基于节点流程式的stable diffusion AI 绘图工具WebUI&#xff0c; 通过将stable diffusion的流程拆分成节点&#xff0c;实现了更加精准的工作流定制和完善的可复现性。 ComfyUI因为内部生成流程做了优化&#xff0c;生成图片时的速度相较于WebUI有10%~25…

关于字节 c++

字节的介绍 字节是计算机中最小的存储单位&#xff0c;通常由8个二进制位组成&#xff0c;用来存储一个字符。在C中&#xff0c;字节也是基本数据类型之一&#xff0c;用关键字"byte"来表示。字节主要用于存储一些较小的数据&#xff0c;如整数、字符等。字节的大小…

音频转MP3格式困难?如何轻松实现wav转mp3?

格式多样化为我们带来了灵活性和创意的无限可能&#xff0c;但同时&#xff0c;不同格式间的转换也成为了不少用户面临的难题。尤其是当你手握珍贵的WAV音频文件&#xff0c;却希望它们能在更多设备上流畅播放或节省存储空间时&#xff0c;wav转mp3的需求便应运而生。WAV以其无…

网络安全中的 EDR 是什么:概述和功能

专业知识&#xff1a;EDR、XDR、NDR 和 MDR_xdr edr ndr-CSDN博客 端点检测和响应 (EDR) 是一种先进的安全系统&#xff0c;用于检测、调查和解决端点上的网络攻击。它可以检查事件、检查行为并将系统恢复到攻击前的状态。EDR 使用人工智能、机器学习和威胁情报来避免再次发生攻…

c语言实现:链表创建、插入、删除、翻转

#include <stdio.h> #include <stdlib.h>// 链表创建 typedef struct Node{int data;struct Node* next; } Node;// 创建一个节点 Node* createNode(int data){Node* newNode (Node* )malloc(sizeof(Node));newNode->data data;newNode->next NULL;return…

35岁java转大模型笔记,大模型智能体(LLM Agent)学习笔记

\1. 什么是大模型&#xff1f; 大模型对应的英文是Large Language Model&#xff08;LLM&#xff09;&#xff0c;即大语言模型&#xff0c;简称大模型。技术层面讲&#xff0c;大模型是一种基于深度学习技术的机器学习模型。 为什么叫大模型呢&#xff1f;它是相对于小模型而…

万界星空科技铜拉丝行业MES系统,实现智能化转型

一、铜拉丝行业生产管理的难点主要体现在以下几个方面&#xff1a; 1、标准严格&#xff1a;铜线产品对质量的要求极高&#xff0c;特别是在电气性能、导电性、耐腐蚀性等方面&#xff0c;任何微小的瑕疵都可能影响产品的使用效果和安全性。 2、过程监控&#xff1a;生产过程…

点赞10万+,1分钟教会你,用AI生成的宠物带娃视频

今天刷到了这样的宠物带娃视频&#xff0c;最近这种视频爆火&#xff0c;出现了很多爆款&#xff0c;今天就拆解一下&#xff0c;教大家学会这种视频用AI如何生成。 我们先看一下这类视频的数据&#xff0c;很多账号都在做&#xff0c;对于不了解AI的人来说&#xff0c;会觉得…