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

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知识宝典》 


http://www.kler.cn/a/466781.html

相关文章:

  • [读书日志]从零开始学习Chisel 第一篇:书籍介绍,Scala与Chisel概述,Scala安装运行(敏捷硬件开发语言Chisel与数字系统设计)
  • Linux运维相关基础知识(二)
  • Android中创建ViewModel的几种方法
  • 音视频入门基础:MPEG2-PS专题(5)——FFmpeg源码中,解析PS流中的PES流的实现
  • 现代光学基础5
  • 使用SSH建立内网穿透,能够访问内网的web服务器
  • 【51单片机零基础-chapter3:按键:独立按键|||附带常见C语句.逻辑运算符】
  • 中国科技产业化促进会深入深圳企业调研
  • gesp(C++一级)(17)洛谷:B4062:[GESP202412 一级] 温度转换
  • 在Linux系统中使用字符图案和VNC运行Qt Widgets程序
  • IDEA Plugins中搜索不到插件解决办法
  • 自动化测试常考的面试题+答案汇总(持续更新)
  • React 网络请求优化
  • CVSS漏洞评分系统曝出严重缺陷
  • 【源码+文档+调试讲解】“健康早知道”微信小程序
  • 生成对抗网络 (Generative Adversarial Network, GAN) 算法MNIST图像生成任务及CelebA图像超分辨率任务
  • 深入理解 Android 中的 ComponentInfo
  • Hive集群安装部署
  • Markdown中流程图的用法
  • 解决 HTML 表单输入框与按钮对齐问题
  • LeetCode 力扣 热题 100道(二十三)找到字符串中所有字母异位词(C++)
  • issue问题全解
  • 从摩托罗拉手机打印短信的简单方法
  • 深入 Redis:高级特性与最佳实践
  • 下载Stegsolve.jar后运行报错 ”Error: Unable to access jarfile stegslove. ”
  • Hive分区表添加字段