perf:对hutool的BeanUtil工具类做补充

news2025/1/8 0:54:32

分享一个自定义的BeanUtil,继承的是hutool的工具类,然后自己扩充了几个方法;

1、实现了两个对象覆盖非空属性的功能(经常使用),不需要设置CopyOptions;

2、两个对象,对指定前缀的属性进行拷贝,其中copyExtendProperties就会拷贝对象中的extend1,extend2,extend3...等等。

@Slf4j
@UtilityClass
public class MyBeanUtils extends BeanUtil {

    /**
     * 两个对象覆盖非空属性(忽略指定字段)
     *
     * @param source        源 bean
     * @param target        目标 bean
     * @param ignoresFields 忽略的字段列表
     */
    public static <S, T> void overrideNonNullProperties(S source, T target, String... ignoresFields) {
        Map<String, Object> sourceMap = BeanUtil.beanToMap(source, false, false);
        Map<String, Object> targetMap = BeanUtil.beanToMap(target, false, false);
        overrideNonNullPropertiesInternal(sourceMap, target, targetMap, ignoresFields);
    }

    /**
     * 将 Map 赋值非空属性到指定对象(忽略指定字段)
     *
     * @param sourceMap     源 Map
     * @param target        目标 bean
     * @param ignoresFields 忽略的字段列表
     */
    public static <T> void overrideNonNullProperties(Map<String, Object> sourceMap, T target, String... ignoresFields) {
        Map<String, Object> targetMap = BeanUtil.beanToMap(target, false, false);
        overrideNonNullPropertiesInternal(sourceMap, target, targetMap, ignoresFields);
    }

    /**
     * 内部方法,处理覆盖非空属性的逻辑
     *
     * @param sourceMap     源对象的属性映射
     * @param target        目标对象
     * @param targetMap     目标对象的属性映射
     * @param ignoresFields 忽略的字段列表
     */
    private static <T> void overrideNonNullPropertiesInternal(Map<String, Object> sourceMap, T target,
                                                              Map<String, Object> targetMap, String... ignoresFields) {
        // 移除忽略的字段
        for (String field : ignoresFields) {
            targetMap.remove(field);
        }

        // 遍历源对象的属性,只处理非空值,并确认目标对象中存在该字段
        sourceMap.forEach((fieldName, value) -> {
            if (value != null && targetMap.containsKey(fieldName)) {
                BeanUtil.setFieldValue(target, fieldName, value);
            }
        });
    }

    /**
     * 将源对象的属性通过反射赋值到目标对象(只处理以 "extend" 开头的字段)
     *
     * @param source 源对象
     * @param target 目标对象
     */
    public static void copyExtendProperties(Object source, Object target) {
        copyPropertiesWithPrefix(source, target, "extend");
    }

    /**
     * 将源对象的属性通过反射赋值到目标对象(只处理以指定前缀开头的字段)
     *
     * @param source             源对象
     * @param target             目标对象
     * @param propertyNamePrefix 处理的字段名前缀
     * @param ignoresFields      忽略的字段列表
     */
    public static void copyPropertiesWithPrefix(Object source, Object target, String propertyNamePrefix, String... ignoresFields) {
        Field[] fields = source.getClass().getDeclaredFields();
        Set<String> ignoresSet = Set.of(ignoresFields);

        for (Field field : fields) {
            String fieldName = field.getName();

            if (fieldName.startsWith(propertyNamePrefix)) {
                try {
                    ReflectionUtils.makeAccessible(field);
                    Object value = field.get(source);

                    if (value != null) {
                        Field targetField = getTargetField(fieldName, target.getClass());

                        if (targetField != null && !ignoresSet.contains(fieldName)) {
                            ReflectionUtils.makeAccessible(targetField);
                            ReflectionUtils.setField(targetField, target, value);
                        }
                    }
                } catch (IllegalAccessException e) {
                    log.error("非法访问字段: {}", fieldName, e);
                }
            }
        }
    }

    /**
     * 安全地获取目标对象中的字段。
     *
     * @param fieldName 字段名
     * @param clazz     目标对象的类对象
     * @return 目标字段或null(如果未找到)
     */
    private static Field getTargetField(String fieldName, Class<?> clazz) {
        try {
            Field field = ReflectionUtils.findField(clazz, fieldName);
            if (field == null) {
                log.debug("目标对象中未找到字段: {}", fieldName);
            }
            return field;
        } catch (Exception e) {
            log.error("获取目标字段异常: {}", fieldName, e);
            return null;
        }
    }
}

ps:以下是我整理的java面试资料,感兴趣的可以看看。最后,创作不易,觉得写得不错的可以点点关注!

链接:https://www.yuque.com/u39298356/uu4hxh?# 《Java知识宝典》 

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

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

相关文章

【C++】B2101 计算矩阵边缘元素之和

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;题目背景与描述题目描述输入格式输出格式输入输出样例说明与提示 &#x1f4af;分析与解决方案解法一&#xff1a;我的做法代码实现解题思路优点与局限性 解法二&#xff1…

【软考网工笔记】计算机基础理论与安全——计算机硬件知识

计算机分级存储体系 计算机分级存储体系目前最常用的是三级存储体系。 CPU——CaChe&#xff08;高速缓存&#xff09;——主存——辅存 其中 Cache 是用于解决存取速度不够快&#xff0c;辅存是用于解决存储容量不够大&#xff0c;二者结合可在容量和速度实现提升的情况下尽可…

回归预测 | MATLAB实ELM-Adaboost多输入单输出回归预测

回归预测 | MATLAB实ELM-Adaboost多输入单输出回归预测 目录 回归预测 | MATLAB实ELM-Adaboost多输入单输出回归预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 一、极限学习机&#xff08;ELM&#xff09; 极限学习机是一种单层前馈神经网络&#xff0c;具有训练速…

【MATLAB】【Simulink仿真】向模型中添加自定义子系统

一、子系统的创建 1、启动Simulink&#xff0c;选择【新建】——【空白子系统】——【创建子系统】 2、选择【浏览组件库】&#xff0c;创建使能子系统。 3、保存至当前工作目录。 二、建立模型仿真 1、启动Simulink&#xff0c;选择【新建】——【空白子系统】——【创建子系…

国产编辑器EverEdit - 使用技巧:变量重命名的一种简单替代方法

1 使用技巧&#xff1a;变量重命名的一种简单替代方法 1.1 应用场景 写过代码的都知道&#xff0c;经常添加功能的时候&#xff0c;是把别的地方的代码拷贝过来&#xff0c;改吧改吧&#xff0c;就能用了&#xff0c;改的过程中&#xff0c;就涉及到一个变量名的问题&#xff…

手持PDA终端,提升零售门店管理效率

随着科技的不断进步和零售行业的持续发展&#xff0c;手持PDA终端的应用将会越来越广泛。它将不断融合更多先进的技术和功能&#xff0c;为零售门店管理带来更加便捷、高效、智能的解决方案。 手持PDA终端是集成了数据处理、条码扫描、无线通信等多种功能于一体的便携式设备‌…

机器学习之逻辑回归算法、数据标准化处理及数据预测和数据的分类结果报告

逻辑回归算法、数据标准化处理及数据预测和数据的分类结果报告 目录 逻辑回归算法、数据标准化处理及数据预测和数据的分类结果报告1 逻辑回归算法1.1 概念理解1.2 算法导入1.3 算法优缺点 2 LogisticRegression理解2.1查看参数定义2.2 参数理解2.3 方法2.4基本格式 3 数据标准…

ICLR2017 | Ens | 深入研究可迁移的对抗样本和黑盒攻击

Delving Into Transferable Adversarial Examples And Black-Box Attacks 摘要-Abstract引言-Introduction对抗深度学习和可迁移性-Adversarial Deep Learning And Transferability对抗深度学习问题生成对抗样本的方法评估方法 非目标性对抗样本-Non-Targeted Adversarial Exam…

在IDEA中如何用git拉取远程某一分支的代码

想要在idea中拉取远程某一分支的代码&#xff0c;我们可以在idea中使用git命令 1.选择idea的Terminal窗口 2.使用git -v 命令查看一下git的版本&#xff0c;顺便测试一下能否使用git命令&#xff08;不能使用的话需要在idea中进行相关配置&#xff09; 3.使用 git fetch命令更新…

【博主推荐】 Microi吾码开源低代码平台,快速建站,提高开发效率

&#x1f36c;引言 &#x1f36c;什么是低代码平台&#xff1f; 低代码平台&#xff08;Low-Code Platform&#xff09;是一种使开发人员和业务用户可以通过图形化界面和少量的编程来创建应用程序的开发工具。与传统的编程方式相比&#xff0c;低代码平台大大简化了开发过程&a…

基于51单片机(STC32G12K128)和8X8彩色点阵屏(WS2812B驱动)的小游戏《贪吃蛇》

目录 系列文章目录前言一、效果展示二、原理分析三、各模块代码1、定时器02、矩阵按键模块3、8X8彩色点阵屏 四、主函数总结 系列文章目录 前言 《贪吃蛇》&#xff0c;一款经典的、怀旧的小游戏&#xff0c;单片机入门必写程序。 以《贪吃蛇》为载体&#xff0c;熟悉各种屏幕…

【开源】创建自动签到系统—QD框架

1. 介绍 QD是一个 基于 HAR 编辑器和 Tornado 服务端的 HTTP 定时任务自动执行 Web 框架。 主要通过抓包获取到HAR来制作任务模板&#xff0c;从而实现异步响应和发起HTTP请求 2. 需要环境 2.1 硬件需求 CPU&#xff1a;至少1核 内存&#xff1a;推荐 ≥ 1G 硬盘&#xff1a;推…

【区块链】零知识证明基础概念详解

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 零知识证明基础概念详解引言1. 零知识证明的定义与特性1.1 基本定义1.2 三个核心…

豆包ai 生成动态tree 增、删、改以及上移下移 html+jquery

[豆包ai 生成动态tree 增、删、改以及上移下移 htmljquery) 人工Ai 编程 推荐一Kimi https://kimi.moonshot.cn/ 推荐二 豆包https://www.doubao.com/ 实现效果图 html 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF…

Redis(一)基本特点和常用全局命令

目录 一、Redis 的基本特点 1、速度快&#xff08;但空间有限&#xff09; 2、储存键值对的“非关系型数据库” 3、 功能丰富 4、 支持集群 5、支持持久化 6、主从复制架构 二、Redis 的典型应用场景 1、作为存储热点数据的缓存 2、作为消息队列服务器 3、作为把数据…

SpringMVC(三)请求

目录 一、RequestMapping注解 1.RequestMapping的属性 实例 1.在这里创建文件&#xff0c;命名为Test: 2.复现-返回一个页面&#xff1a; 创建test界面&#xff08;随便写点什么&#xff09;&#xff1a; Test文件中编写&#xff1a; ​编辑 运行&#xff1a; 3.不返回…

K8s集群平滑升级(Smooth Upgrade of K8S Cluster)

简介&#xff1a; Kubernetes ‌ &#xff08;简称K8s&#xff09;是一个开源的容器编排和管理平台&#xff0c;由Google开发并维护。它最初是为了解决谷歌内部大规模容器管理的问题而设计的&#xff0c;后来在2014年开源&#xff0c;成为云原生技术的核心组成部分。‌‌1 K8…

NO.1 《机器学习期末复习篇》以题(问答题)促习(人学习),满满干huo,大胆学大胆补!

目录 一、新手初学&#xff1f;该如何区分[人工智能] [机器学习] [深度学习]&#xff1f; [1]浅谈一下我的理解 [2]深度交流一下 人工智能&#xff08;AI, Artificial Intelligence&#xff09; 机器学习&#xff08;ML, Machine Learning&#xff09; 深度学习&#xff0…

零基础也能建站: 使用 WordPress 和 US Domain Center 轻松五步创建网站 (无需编程)

创建一个网站可能听起来很复杂&#xff0c;但只要使用正确的工具&#xff0c;你可以通过五个简单步骤构建一个专业网站 — — 无需编写任何代码&#xff01;在本教程中&#xff0c;我们将使用 WordPress 和 US Domain Center 指导你完成整个过程。完成后&#xff0c;你将拥有一…

pdf预览 报:Failed to load module script

pdf 预览报&#xff1a; Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of “application/octet-stream”. Strict MIME type checking is enforced for module scripts per HTML spec. 报错原因&#xff1a…