实现忽略大小写的 copyProperties

本贴最后更新于 2163 天前,其中的信息可能已经时异事殊

实现的原因

Spring 中的 BeanUtils.copyProperties(source,target),不能忽略大小写,类型不同不能相互赋值。速度并不是特别理想。自己根据反射实现了工具类。
其中 ReflectASM 需要引入下面 jar 包

<!---RelectAsm--> <dependency> <groupId>com.esotericsoftware</groupId> <artifactId>reflectasm</artifactId> <version>1.11.7</version> </dependency>

#具体代码

import com.esotericsoftware.reflectasm.MethodAccess; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.*; /** * * @Auther: xjw * @Description: 此类主要用于反射,对反射的一些操作进行缓存起来。 */ public class BeanUtils { /** * 集合 copy * * @param sources * @param target * @param <T> * @return */ public static <T> List<T> listCopyPropertiesASM(List sources, Class<T> target) { List list = new ArrayList<>(sources.size()); sources.forEach(it -> { list.add(copyPropertiesASM(it, target)); }); return list; } /** * 通过 target的Class 复制 * target 必须有一个无参构造器 * * @param source * @param target * @param <T> * @return */ public static <T> T copyPropertiesASM(Object source, Class<T> target) { T newT = null; try { newT = target.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return copyPropertiesASM(source, newT); } /** * 通过 ASM反射 速度比 Spring BeanUtils.copyProperties(source,target) 快一倍 * 大小写可以忽略 * 下划线 _ 被忽略 * * @param source 源对象 * @param target 目标实例化对象 * @param <T> * @return */ public static <T> T copyPropertiesASM(Object source, Object target) { MethodAccess sourceMethodAccess = CacheMethodAccess.getMethodAccess(source.getClass()); MethodAccess targetMethodAccess = CacheMethodAccess.getMethodAccess(target.getClass()); Map<String, String> sourceGet = CacheAsmFiledMethod.getMethod("get", source.getClass()); Map<String, String> targetSet = CacheAsmFiledMethod.getMethod("set", target.getClass()); CacheFieldMap.getFieldMap(target.getClass()).keySet().forEach((it) -> { String sourceIndex = sourceGet.get(it); if (sourceIndex != null) { Object value = sourceMethodAccess.invoke(source, sourceIndex); String setIndex = targetSet.get(it); targetMethodAccess.invoke(target, setIndex, value); } }); return (T) target; } /** * 模仿Spring中 BeanUtils.copyProperties(source,target) * 大小写可以忽略 * 下划线 _ 被忽略 * * @param source * @param target * @param <T> * @return */ public static <T> T copyProperties(Object source, Object target) { Map<String, Field> sourceMap = CacheFieldMap.getFieldMap(source.getClass()); CacheFieldMap.getFieldMap(target.getClass()).values().forEach((it) -> { Field field = sourceMap.get(it.getName().toLowerCase().replace("_", "")); if (field != null) { it.setAccessible(true); field.setAccessible(true); try { it.set(target, field.get(source)); } catch (IllegalAccessException e) { e.printStackTrace(); } } }); return (T) target; } private static class CacheAsmFiledMethod { private static Map<String, Map<String, String>> cacheGetMethod = new HashMap<>(); private static Map<String, Map<String, String>> cacheSetMethod = new HashMap<>(); private static Map<String, String> getMethod(String type, Class clazz) { MethodAccess methodAccess = CacheMethodAccess.getMethodAccess(clazz); Map<String, Field> allFields = CacheFieldMap.getFieldMap(clazz); Map<String, String> result = null; if (type.equals("get")) { result = cacheGetMethod.get(clazz.getName()); } else if (type.equals("set")) { result = cacheSetMethod.get(clazz.getName()); } if (result == null) { synchronized (CacheAsmFiledMethod.class) { if (result == null) { Map<String, String> set = new HashMap<>(); Map<String, String> get = new HashMap<>(); allFields.values().forEach((it) -> { //判断是否是静态 if (!Modifier.isStatic(it.getModifiers())) { //首字母大写 char[] f = it.getName().toCharArray(); f[0] -= 32; String fieldName = new String(f); get.put(fieldName.toLowerCase().replace("_", ""), "get" + fieldName); set.put(fieldName.toLowerCase().replace("_", ""), "set" + fieldName); } }); cacheGetMethod.put(clazz.getName(), get); cacheSetMethod.put(clazz.getName(), set); if (type.equals("get")) { result = cacheGetMethod.get(clazz.getName()); } else if (type.equals("set")) { result = cacheSetMethod.get(clazz.getName()); } } } } return result; } } private static class SingelClass { private static Map<String, Object> cacheObject = new HashMap<>(); private SingelClass() { } private static <T> T getObject(Class<T> clazz) { T result = (T) cacheObject.get(clazz.getName()); if (result == null) { synchronized (SingelClass.class) { if (result == null) { try { cacheObject.put(clazz.getName(), clazz.newInstance()); result = (T) cacheObject.get(clazz.getName()); } catch (Exception e) { e.printStackTrace(); } } } } return result; } } private static class CacheMethodAccess { private CacheMethodAccess() { } private static Map<String, MethodAccess> cache = new HashMap<>(); private static MethodAccess getMethodAccess(Class clazz) { MethodAccess result = cache.get(clazz.getName()); if (result == null) { synchronized (CacheMethodAccess.class) { if (result == null) { cache.put(clazz.getName(), MethodAccess.get(clazz)); result = cache.get(clazz.getName()); } } } return result; } } private static class CacheFieldMap { private static Map<String, Map<String, Field>> cacheMap = new HashMap<>(); private static Map<String, Field> getFieldMap(Class clazz) { Map<String, Field> result = cacheMap.get(clazz.getName()); if (result == null) { synchronized (CacheFieldMap.class) { if (result == null) { Map<String, Field> fieldMap = new HashMap<>(); for (Field field : clazz.getDeclaredFields()) { fieldMap.put(field.getName().toLowerCase().replace("_", ""), field); } cacheMap.put(clazz.getName(), fieldMap); result = cacheMap.get(clazz.getName()); } } } return result; } } }

测试

public static void main(String[] args) { Man man = new Man("name", 20); Woman woman = BeanUtils.copyPropertiesASM(man, Woman.class); System.out.println(woman); List<Man> manList = new ArrayList<>(); for (int i = 0; i < 100; i++) { manList.add(new Man("name" + i, i)); } List<Woman> womens = BeanUtils.listCopyPropertiesASM(manList,Woman.class); System.out.println(womens); }
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3201 引用 • 8217 回帖 • 1 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • Python

    Python 是一种面向对象、直译式电脑编程语言,具有近二十年的发展历史,成熟且稳定。它包含了一组完善而且容易理解的标准库,能够轻松完成很多常见的任务。它的语法简捷和清晰,尽量使用无异义的英语单词,与其它大多数程序设计语言使用大括号不一样,它使用缩进来定义语句块。

    554 引用 • 675 回帖
  • WebClipper

    Web Clipper 是一款浏览器剪藏扩展,它可以帮助你把网页内容剪藏到本地。

    3 引用 • 9 回帖
  • webpack

    webpack 是一个用于前端开发的模块加载器和打包工具,它能把各种资源,例如 JS、CSS(less/sass)、图片等都作为模块来使用和处理。

    42 引用 • 130 回帖 • 252 关注
  • 正则表达式

    正则表达式(Regular Expression)使用单个字符串来描述、匹配一系列遵循某个句法规则的字符串。

    31 引用 • 94 回帖
  • Tomcat

    Tomcat 最早是由 Sun Microsystems 开发的一个 Servlet 容器,在 1999 年被捐献给 ASF(Apache Software Foundation),隶属于 Jakarta 项目,现在已经独立为一个顶级项目。Tomcat 主要实现了 JavaEE 中的 Servlet、JSP 规范,同时也提供 HTTP 服务,是市场上非常流行的 Java Web 容器。

    162 引用 • 529 回帖 • 9 关注
  • SOHO

    为成为自由职业者在家办公而努力吧!

    7 引用 • 55 回帖
  • 强迫症

    强迫症(OCD)属于焦虑障碍的一种类型,是一组以强迫思维和强迫行为为主要临床表现的神经精神疾病,其特点为有意识的强迫和反强迫并存,一些毫无意义、甚至违背自己意愿的想法或冲动反反复复侵入患者的日常生活。

    15 引用 • 161 回帖 • 2 关注
  • OpenCV
    15 引用 • 36 回帖 • 4 关注
  • 小说

    小说是以刻画人物形象为中心,通过完整的故事情节和环境描写来反映社会生活的文学体裁。

    32 引用 • 108 回帖
  • 智能合约

    智能合约(Smart contract)是一种旨在以信息化方式传播、验证或执行合同的计算机协议。智能合约允许在没有第三方的情况下进行可信交易,这些交易可追踪且不可逆转。智能合约概念于 1994 年由 Nick Szabo 首次提出。

    1 引用 • 11 回帖 • 2 关注
  • VirtualBox

    VirtualBox 是一款开源虚拟机软件,最早由德国 Innotek 公司开发,由 Sun Microsystems 公司出品的软件,使用 Qt 编写,在 Sun 被 Oracle 收购后正式更名成 Oracle VM VirtualBox。

    10 引用 • 2 回帖 • 17 关注
  • WordPress

    WordPress 是一个使用 PHP 语言开发的博客平台,用户可以在支持 PHP 和 MySQL 数据库的服务器上架设自己的博客。也可以把 WordPress 当作一个内容管理系统(CMS)来使用。WordPress 是一个免费的开源项目,在 GNU 通用公共许可证(GPLv2)下授权发布。

    46 引用 • 114 回帖 • 168 关注
  • GitHub

    GitHub 于 2008 年上线,目前,除了 Git 代码仓库托管及基本的 Web 管理界面以外,还提供了订阅、讨论组、文本渲染、在线文件编辑器、协作图谱(报表)、代码片段分享(Gist)等功能。正因为这些功能所提供的便利,又经过长期的积累,GitHub 的用户活跃度很高,在开源世界里享有深远的声望,并形成了社交化编程文化(Social Coding)。

    209 引用 • 2040 回帖
  • 区块链

    区块链是分布式数据存储、点对点传输、共识机制、加密算法等计算机技术的新型应用模式。所谓共识机制是区块链系统中实现不同节点之间建立信任、获取权益的数学算法 。

    92 引用 • 752 回帖
  • CAP

    CAP 指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可兼得。

    12 引用 • 5 回帖 • 634 关注
  • B3log

    B3log 是一个开源组织,名字来源于“Bulletin Board Blog”缩写,目标是将独立博客与论坛结合,形成一种新的网络社区体验,详细请看 B3log 构思。目前 B3log 已经开源了多款产品:SymSoloVditor思源笔记

    1063 引用 • 3455 回帖 • 151 关注
  • 阿里巴巴

    阿里巴巴网络技术有限公司(简称:阿里巴巴集团)是以曾担任英语教师的马云为首的 18 人,于 1999 年在中国杭州创立,他们相信互联网能够创造公平的竞争环境,让小企业通过创新与科技扩展业务,并在参与国内或全球市场竞争时处于更有利的位置。

    43 引用 • 221 回帖 • 58 关注
  • Git

    Git 是 Linux Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。

    211 引用 • 358 回帖
  • 机器学习

    机器学习(Machine Learning)是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。

    77 引用 • 37 回帖
  • Chrome

    Chrome 又称 Google 浏览器,是一个由谷歌公司开发的网页浏览器。该浏览器是基于其他开源软件所编写,包括 WebKit,目标是提升稳定性、速度和安全性,并创造出简单且有效率的使用者界面。

    63 引用 • 289 回帖
  • Unity

    Unity 是由 Unity Technologies 开发的一个让开发者可以轻松创建诸如 2D、3D 多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

    25 引用 • 7 回帖 • 121 关注
  • 又拍云

    又拍云是国内领先的 CDN 服务提供商,国家工信部认证通过的“可信云”,乌云众测平台认证的“安全云”,为移动时代的创业者提供新一代的 CDN 加速服务。

    20 引用 • 37 回帖 • 578 关注
  • 叶归
    12 引用 • 56 回帖 • 22 关注
  • IPFS

    IPFS(InterPlanetary File System,星际文件系统)是永久的、去中心化保存和共享文件的方法,这是一种内容可寻址、版本化、点对点超媒体的分布式协议。请浏览 IPFS 入门笔记了解更多细节。

    20 引用 • 245 回帖 • 233 关注
  • CSS

    CSS(Cascading Style Sheet)“层叠样式表”是用于控制网页样式并允许将样式信息与网页内容分离的一种标记性语言。

    198 引用 • 543 回帖
  • C++

    C++ 是在 C 语言的基础上开发的一种通用编程语言,应用广泛。C++ 支持多种编程范式,面向对象编程、泛型编程和过程化编程。

    108 引用 • 153 回帖
  • OpenStack

    OpenStack 是一个云操作系统,通过数据中心可控制大型的计算、存储、网络等资源池。所有的管理通过前端界面管理员就可以完成,同样也可以通过 Web 接口让最终用户部署资源。

    10 引用 • 2 关注