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

分享一个自定义的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知识宝典》 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

windows编译llama.cpp GPU版本

Build 指南 https://github.com/ggerganov/llama.cpp/blob/master/docs/build.md 一、Prerequire 具体步骤&#xff08;以及遇到的坑&#xff09;&#xff1a; 如果你要使用CUDA&#xff0c;请确保已安装。 1.安装 最新的 cmake, git, anaconda&#xff0c; pip 配置pyt…

Android 性能优化:内存优化(实践篇)

1. 前言 前一篇文章Android性能优化&#xff1a;内存优化 &#xff08;思路篇&#xff09; 大概梳理了Android 内存原理和优化的必要性及应该如何优化&#xff0c;输出了一套短期和长期内存优化治理的SOP方案。 那么这一篇文章就总结下我最近在做内存优化如何实践的&#xff0…

「Mac畅玩鸿蒙与硬件53」UI互动应用篇30 - 打卡提醒小应用

本篇教程将实现一个打卡提醒小应用&#xff0c;通过用户输入时间进行提醒设置&#xff0c;并展示实时提醒状态&#xff0c;实现提醒设置和取消等功能。 关键词 打卡提醒状态管理定时任务输入校验UI交互 一、功能说明 打卡提醒小应用包含以下功能&#xff1a; 提醒时间输入与…

Nginx知识详解(理论+实战更易懂)

目录 一、Nginx架构和安装 1.1 Nginx 概述 1.1.1 nginx介绍 1.1.2?Nginx 功能介绍 1.1.3?基础特性 1.1.4?Web 服务相关的功能 1.2?Nginx 架构和进程 1.2.1?Nginx 进程结构 1.2.2?Nginx 进程间通信 1.2.3?Nginx 启动和 HTTP 连接建立 1.2.4?HTTP 处理过程 1…

Postgresql 命令还原数据库

因为PgAdmin打不开&#xff0c;但是数据库已经安装成功了&#xff0c;这里借助Pg命令来还原数据库 C:\Program Files\PostgreSQL\15\bin\psql.exe #链接数据库 psql -U postgres -p 5432#创建数据库 CREATE DATABASE "数据库名称"WITHOWNER postgresENCODING UTF8…

Vue 解决浏览器刷新路由参数丢失问题 全局统一配置无需修改组件

在路由跳转的时候,我们经常会传一些参数过去,然后通过传过来的参数调用接口获取相关数据,但是刷新浏览器的时候路由参数会丢失。此时页面报错误了,如何通过全局配置的方式,不需要修改任何组件 实现刷新浏览器保存参数? 实现方式如下: 首先在router/index.js里添加参数管…

【AIGC】电话录音转文字实践:基于Google Cloud Speech-to-Text-v1的技术方案Python

文章目录 引言技术原理技术方案设计系统架构关键技术要点 代码实现1. 环境准备2. 核心代码实现3. 音频预处理工具响应格式 性能优化实践经验应用场景未来展望总结 引言 在当今数字化时代&#xff0c;将语音内容转换为文字已经成为一个非常重要的技术需求。无论是客服通话记录、…

RabbitMQ-基本使用

RabbitMQ: One broker to queue them all | RabbitMQ 官方 安装到Docker中 docker run \-e RABBITMQ_DEFAULT_USERrabbit \-e RABBITMQ_DEFAULT_PASSrabbit \-v mq-plugins:/plugins \--name mq \--hostname mq \-p 15672:15672 \-p 5672:5672 \--network mynet\-d \rabbitmq:3…

Android Camera压力测试工具

背景描述&#xff1a; 随着系统的复杂化和业务的积累&#xff0c;日常的功能性测试已不足以满足我们对Android Camera相机系统的测试需求。为了确保Android Camera系统在高负载和多任务情况下的稳定性和性能优化&#xff0c;需要对Android Camera应用进行全面的压测。 对于压…

vscode中调用deepseek实现AI辅助编程

来自 Python大数据分析 费弗里 1 简介 大家好我是费老师&#xff0c;最近国产大模型Deepseek v3新版本凭借其优秀的模型推理能力&#xff0c;讨论度非常之高&#x1f525;&#xff0c;且其官网提供的相关大模型API接口服务价格一直走的“价格屠夫”路线&#xff0c;性价比很高…

基于 LMS 算法的离散傅里叶分析器

基于 LMS&#xff08;Least Mean Squares&#xff0c;最小均方&#xff09;算法的离散傅里叶分析器是一种结合自适应滤波和频域分析的工具&#xff0c;用于动态估计信号的频谱成分。它将 LMS 自适应算法与离散傅里叶变换&#xff08;DFT&#xff09;的频率分解能力结合&#xf…

2022浙江大学信号与系统笔记

原视频地址&#xff1a;2022浙江大学信号与系统&#xff08;含配套课件和代码&#xff09; - 胡浩基老师-哔哩哔哩 ⭐⭐⭐ 我的笔记&#xff1a;飞书链接 - 信号与系统 基于视频&#xff0c;记得笔记&#xff0c;加了点自己的补充&#xff08;有的是问 ChatGPT 的&#xff09;…

K8s高可用集群之Kubernetes集群管理平台、命令补全工具、资源监控工具部署、常用命令

K8s高可用集群之Kubernetes管理平台、补全命令工具、资源监控工具部署 1.Kuboard可视化管理平台2.kubectl命令tab补全工具3.MetricsServer资源监控工具4.Kubernetes常用命令 1.Kuboard可视化管理平台 可以选择安装k8s官网的管理平台&#xff1b;我这里是安装的其他开源平台Kub…

Gitlab-runner 修改默认的builds_dir并使用custom_build_dir配置

gitlab-runner 修改默认的builds_dir并使用custom_build_dir配置 1. 说明2. 实操&#xff08;以docker执行器为例&#xff09;2.1 修改默认的builds_dir2.1.1 调整gitlab-runner的配置文件2.1.2 CI文件 2.2 启用custom_build_dir2.2.1 调整gitlab-runner的配置文件2.2.2 CI文件…

网络IP协议

IP&#xff08;Internet Protocol&#xff0c;网际协议&#xff09;是TCP/IP协议族中重要的协议&#xff0c;主要负责将数据包发送给目标主机。IP相当于OSI&#xff08;图1&#xff09;的第三层网络层。网络层的主要作用是失陷终端节点之间的通信。这种终端节点之间的通信也叫点…

SpringCloud源码-Ribbon

一、Spring定制化RestTemplate&#xff0c;预留出RestTemplate定制化扩展点 org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration 二、Ribbon定义RestTemplate Ribbon扩展点功能 org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguratio…

MySQL5.7.26-Linux-安装(2024.12)

文章目录 1.下载压缩包1.访问MySQL版本归档2.找到5.7.26并下载3.百度网盘 2.Linux安装1.卸载原来的MySQL8.0.26&#xff08;如果没有则无需在意&#xff09;1.查看所有mysql的包2.批量卸载3.删除残留文件**配置文件**&#xff08;默认路径&#xff09;&#xff1a; 4.**验证卸载…

python修改ppt中的文字部分及插入图片

批量修改ppt中的某个模块&#xff0c;或者批量制作奖状等场景会用到&#xff1b; import os import pandas as pd from pptx import Presentation from pptx.util import Inchesfilepath/Users/kangyongqing/Documents/kangyq/202303/分析模版/批量制作/file1时段预警_副本.pp…

Ubuntu24.04.1 LTS+Win11双系统安装记录

Win11相关 1.用DiskGenius删除硬盘分区 2.关闭win11的BitLocker&#xff0c;否则禁用安全启动后开机时需要帐户密钥&#xff0c;很麻烦。 3.在设备管理器中找到独立显卡&#xff0c;右键禁用。等ubuntu装好显卡驱动后&#xff0c;再进入win启用。 Ubuntu相关 1.Ubuntu24.04在…

covid-vaccine-availability-using-flask-server

使用烧瓶服务器获得 Covid 疫苗 原文:https://www . geesforgeks . org/co vid-疫苗-可用性-使用-烧瓶-服务器/ 在本文中&#xff0c;我们将使用 Flask Server 构建 Covid 疫苗可用性检查器。 我们都知道&#xff0c;整个世界都在遭受疫情病毒的折磨&#xff0c;唯一能帮助我们…