-
2020-06-15 18:49:45
最新项目中要加操作日志,同时要把用户修改了那些字段记录下来,在更新的时候就需要比较之前的数据和现在的数据有哪些不同,这么多类一个一个的比较就太麻烦了,所以打算写一个工具类。
主要思想还是通过反射获取类的属性的getter方法,调用getter方法获取值并比较是否相同,相同就忽略不同就返回属性信息,方法都不复杂,主要是利用反射思想。代码如下:
定义一个类保存比较后的返回值信息@Data public class PropertyModelInfo { //属性名 private String propertyName; // 属性值 private Object value; // 返回值类型 private Class<?> returnType; }
修改后的属性信息:
public class ModifiedPropertyInfo implements Serializable { // 对应的属性名 private String propertyName; // 未修改之前的值 private Object oldValue; // 修改后的值 private Object newValue; }
逻辑代码:
/** * 比较两个对象属性值是否相同 * 如果不同返回修改过的属性信息 * @param oldObj * @param newObj * @param ignoreProperties * @param <T> * @return 修改过的属性字段 */ public static <T> List<ModifiedPropertyInfo> getDifferentProperty(T oldObj , T newObj , String... ignoreProperties){ if (oldObj != null && newObj != null) { // 比较全部字段 if (ignoreProperties == null || ignoreProperties.length > 0) { if (oldObj.equals(newObj)) { return Collections.emptyList(); } } List<PropertyModelInfo> oldObjectPropertyValue = getObjectPropertyValue(oldObj, ignoreProperties); if (!CollectionUtils.isEmpty(oldObjectPropertyValue)) { List<ModifiedPropertyInfo> modifiedPropertyInfos = new ArrayList<>(oldObjectPropertyValue.size()); List<PropertyModelInfo> newObjectPropertyValue = getObjectPropertyValue(newObj, ignoreProperties); Map<String , Object> objectMap = new HashMap<>(newObjectPropertyValue.size()); // 获取新对象所有属性值 for (PropertyModelInfo propertyModelInfo : newObjectPropertyValue) { String propertyName = propertyModelInfo.getPropertyName(); Object value = propertyModelInfo.getValue(); objectMap.put(propertyName , value); } for (PropertyModelInfo propertyModelInfo : oldObjectPropertyValue) { String propertyName = propertyModelInfo.getPropertyName(); Object value = propertyModelInfo.getValue(); if (objectMap.containsKey(propertyName)) { Object newValue = objectMap.get(propertyName); ModifiedPropertyInfo modifiedPropertyInfo = new ModifiedPropertyInfo(); if (value != null && newValue != null) { // 是否相等 boolean equal = false; if (value instanceof BigDecimal) { // BigDecimal 用 equal 比较 if (((BigDecimal) value).compareTo((BigDecimal) newValue) != 0) { equal = true; } }else if (!value.equals(newValue)) { equal = true; } if (equal) { modifiedPropertyInfo.setProperty(propertyName); modifiedPropertyInfo.setOldValue(value); modifiedPropertyInfo.setNewValue(newValue); modifiedPropertyInfos.add(modifiedPropertyInfo); } }else if (value != null || newValue != null){ modifiedPropertyInfo.setProperty(propertyName); modifiedPropertyInfo.setOldValue(value); modifiedPropertyInfo.setNewValue(newValue); modifiedPropertyInfos.add(modifiedPropertyInfo); } } } return modifiedPropertyInfos; } } return Collections.emptyList(); } /** * 通过反射获取对象的属性名称、getter返回值类型、属性值等信息 * @param obj * @param ignoreProperties * @param <T> * @return */ public static <T> List<PropertyModelInfo> getObjectPropertyValue(T obj , String... ignoreProperties){ if (obj != null) { Class<?> objClass = obj.getClass(); PropertyDescriptor[] propertyDescriptors = BeanUtils.getPropertyDescriptors(objClass); List<PropertyModelInfo> modelInfos = new ArrayList<>(propertyDescriptors.length); List<String> ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null); for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { Method readMethod = propertyDescriptor.getReadMethod(); String name = propertyDescriptor.getName(); if (readMethod != null && (ignoreList == null || !ignoreList.contains(name))) { Object invoke = null; Class<?> returnType = readMethod.getReturnType(); try { invoke = readMethod.invoke(obj); PropertyModelInfo propertyModelInfo = new PropertyModelInfo(); propertyModelInfo.setPropertyName(name); propertyModelInfo.setValue(invoke); propertyModelInfo.setReturnType(returnType); modelInfos.add(propertyModelInfo); } catch (IllegalAccessException | InvocationTargetException e) { LOGGER.error("反射获取类【"+objClass.getName()+"】方法异常," , e); } } } return modelInfos; } return Collections.emptyList(); }
测试:
HouseInfo houseInfo = new HouseInfo(); houseInfo.setAddress("test1"); HouseInfo houseInfo2 = new HouseInfo(); houseInfo2.setAddress("test2"); //改变值 List<ModifiedPropertyInfo> modifiedPropertyInfos = ReflectUtil.getDifferentProperty(houseInfo, houseInfo2); System.out.println(modifiedPropertyInfos); // 不改变值 houseInfo2.setAddress("test1"); modifiedPropertyInfos = ReflectUtil.getDifferentProperty(houseInfo, houseInfo2); System.out.println(modifiedPropertyInfos);
结果:
[ModifiedPropertyInfo(propertyName=address, oldValue=test1, newValue=test2)] []
步骤:
1、获取对象的属性属性值
2、跟另一个对象的所有属性值比较能力一般,水平有限,如有错误,请多指出
更多相关内容 -
JVM快速找出耗内存大对象
2019-07-01 17:42:16当我们的java应用运行时,突然出现内存占用暴增,说明系统中存在长期占用的对象无法回收,或者出现巨大的对象如何快速定位产生的大对象是什么? 找到耗内存的进程 top命令查看你的应用对应的进程ID 1、输入top命令 ...问题
当我们的java应用运行时,突然出现内存占用暴增,说明系统中存在长期占用的对象无法回收,或者出现巨大的对象如何快速定位产生的大对象是什么?
找到耗内存的进程
top命令查看你的应用对应的进程ID
1、输入top命令 然后显示当前系统的整体负载情况,
2、键入m 查看内存使用情况
3、查到指定的进程编号,如上图服务器tomcat进程25085
4、执行如下命令: jmap -histo:live 25085 | head -20 查看进程中占用资源最大的前20个对象备注:
class name表示:
[C is a char[]
[S is a short[]
[I is a int[]
[B is a byte[]
[[I is a int[][]5、从这20个对象中进行分析,一般情况有问题时,这里会有自己工程内的类的大对象,第四列为类名。如果这都无法定位就只能执行dump,将内存快照保存下来用eclipse的MAT工具进行详细分析了
6、知道哪个对象消耗内存了,再去定位代码问题就不难了。 -
【Unity3D 灵巧小知识点】 ☀️ | 快速找到工程中挂载某个脚本的游戏对象
2021-09-27 14:28:55添加到工程中即可 使用方法也很简单,跟第一种方法一样,只不过是使用插件中提供的方法 直接查找工程中所有挂载该脚本的游戏对象 该插件的下载地址放这里了,直接下载放到工程中就可以使用,第一次查找时间会比较长...Unity 小科普
老规矩,先介绍一下 Unity 的科普小知识:
- Unity是 实时3D互动内容创作和运营平台 。
- 包括游戏开发、美术、建筑、汽车设计、影视在内的所有创作者,借助 Unity 将创意变成现实。
- Unity 平台提供一整套完善的软件解决方案,可用于创作、运营和变现任何实时互动的2D和3D内容,支持平台包括手机、平板电脑、PC、游戏主机、增强现实和虚拟现实设备。
- 也可以简单把 Unity 理解为一个游戏引擎,可以用来专业制作游戏!
Unity小知识点学习
快速找到工程中挂载某个脚本的游戏对象
方法一
在Unity中有一个方法可以快速定位到当前场景中挂载某脚本的对象
直接在工程界面右键就可以使用
Find References In Scene
这个方法是查找当前场景中挂载该脚本的游戏对象
方法二在层级面板的搜索框内输入要查询的对象
这样也可以快速查找挂载某脚本的对象,要注意的是只有将脚本的全名输上才能检索到!
方法三
使用插件快速查找工程中挂载某脚本的对象只有三个脚本,添加到工程中即可
使用方法也很简单,跟第一种方法一样,只不过是使用插件中提供的方法
直接查找工程中所有挂载该脚本的游戏对象
该插件的下载地址放这里了,直接下载放到工程中就可以使用,第一次查找时间会比较长,后续就会很快了!
-
VS Code竟然能约会,找对象不看脸,看编程水平
2020-12-14 19:58:29为了用最硬核的方式找到男(女)朋友,23岁的程序员Ben Awad在VS Code里打造一个约会软件VSinder。 顾名思义,VSinder = VS Code + Tinder,就是把约会软件集成到了代码编辑器里,简直太对程序员胃口了。 VSinder和...本文转载自 量子位
VS Code现在居然可以用来谈恋爱了。
为了用最硬核的方式找到男(女)朋友,23岁的程序员Ben Awad在VS Code里打造一个约会软件VSinder。
顾名思义,VSinder = VS Code + Tinder,就是把约会软件集成到了代码编辑器里,简直太对程序员胃口了。
VSinder和Tinder的操作逻辑一样,左滑把不喜欢的人pass掉,右滑收藏喜欢的人。
这款插件一上线,就快速赢得程序员们的认可,GitHub上已收获800 Star,3天的下载量超过9000次。
从代码中找到真爱
既然是面向程序员的约会软件,自然不能和其他约会App一样,一定要有特色。
VSinder的特点就是,可以根据编程语言和代码风格筛选对象。
比如你用的是Python,她用的是C,那么你们之间可能没有共同语言。(以免将来为哪种语言最好吵架。)
对方使用的语言会在人名旁边用一个logo展示出来。
当然,即使用同一种语言编程,水平也有高下,如果对方编程水平达不到自己的要求怎么办?
别怕,VSinder和只看脸的约会软件不同,它是靠代码吸引异性的。(毕竟代码才是程序员的脸面。)
Code Pics一栏填入你最得意的代码,让对方一眼知道你的水平深浅。
VSinder也考虑到性取向问题,你也可以选择约会对象的性别。又或者是你只想找个一起交流代码的同性朋友,只需在程序中选择friendship。
当然,找对象,脸也是很重要的。VSinder暂不支持手动修改头像,而是自动抓取你的GitHub账户,如果想让自己帅(美)一点,只能去修改GitHub头像了。
还有手机App
既然是约会软件,怎么可以只在电脑上运行呢?
虽然手机不能跑VS Code,但是Ben还开发了VSinder的手机App供下载。现已经支持iOS和Android两大系统。
只需登上自己的GitHub账号,完善资料即可使用,和Tinder用起来没啥太大区别,除了没有大量美颜照片。
那么这三天来,有没有人在VSinder上找到男(女)朋友?恐怕是没有,有人滑了半个小时,也没有找到一个单身女程序员。
不过这种情况也不难预料,毕竟GitHub是“全球最大的同性交友社区”。
开源地址:https://github.com/benawad/vsinder
插件下载地址:https://marketplace.visualstudio.com/items?itemName=benawad.vsinder
使用方法介绍:https://www.youtube.com/watch?v=bfd8RyAJh6c
原文地址:https://baijiahao.baidu.com/s?id=1685938252840014575
-
Java编程经验---比较两个List对象差异
2020-06-30 23:40:47Java编程经验---比较两个List对象差异问题引入解决问题简化模型 问题引入 如何比较两个List对象的差异,这个问题来源于我最近正在开发的新系统中的一个细节。大致情况就是,从数据库中的一个视图A向另一个数据库的... -
如何快速对比两个对象中相同字段的值是否相等
2019-10-29 09:17:57我们在做业务逻辑代码书写的时候,经常会遇到这样的问题:用户修改了原来的值,提交给后台以后,后台不仅要更新这条数据的值,有时候还要记录用户做了什么修改,毕竟如果将来出现业务上的问题时,我们可以找出用户的... -
【Js】: 数组对象:在Javascript中如何查找对象数组中的值?
2020-04-20 19:36:40我有一个未命名的对象数组,其中包含一个命名对象的数组,我需要获取“名称”是“字符串1”的对象。这是一个示例数组。 var array = [ { name:"string 1", value:"this", other: "that" }, { name:"string 2", ... -
当年,学姐把这份Java总结给我,让我在22k的校招王者局乱杀
2021-04-22 08:41:36== equals hashcode的关系 1.==是比较两个对象的地址是否相等 2.equals默认和 == 一样也是比较地址,也可以根据自己的需求来重写什么叫做相等 3.hashcode 是根据对象的地址来返回一串int型数字,如果对象不一样的... -
快速判断数组中每个对象同一属性值是否相同(3种方法)
2020-12-08 16:45:25它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员。如果没有符合条件的成员,则返回undefined let demoData = [ {checked:false,name:'royal'}, {... -
Java相同类型的两个对象比较属性值,得到不同属性的名称和对应的值,附代码实例
2018-10-13 12:31:58假设现在有需求如下:比较2个相同类型的不同对象,找到这2个对象的不同的地方,并展示记录一下。当然说的是相互对应的属性啦。 带着这个需求,看下面的例子。(我写代码的都不嫌弃长,你看代码的就也别嫌弃咯。) ... -
JVM成神之路-Java对象模型
2018-07-23 15:01:17在jvm的内存结构中,对象保存在堆中,而我们在对对象进行操作时,其实操作的是对象的引用。 Java对象包含三个部分 一个Java对象可以分为三部分存储在内存中,分别是:对象头(Header)、实例数据(Instance Data)和... -
开源对象存储MinIO技术白皮书
2019-09-27 13:38:36MinIO创始者是Anand Babu Periasamy, Harshavardhana(戒日王)等人, Anand是GlusterFS的初始开发者、Gluster公司的创始人...MinIO在设计上汲取了GlusterFS的相关经验与教训,系统复杂度上作了大量简化。 一、Min... -
Java List对象集快速去重,并将相同对象的属性相加
2018-01-18 09:02:09前言:如果数据量小的话两个for循环足以解决,博主因为项目中涉及到一个将近70w的List集合去重,刚开始用了两个for循环需要20秒的时间,后来发现这个方法可以只用不超过一秒的时间就能完成去重并且将相同对象的属性... -
Java 快速进行对象集合数据比对,For循环嵌套不应该成为你的选择
2019-01-03 14:17:19我们常常用到两个集合的数据比对,找到其中不同的数据,在Android里面基本上数据量也不会太大,往往大家都是直接用for循环嵌套搞定,大家有没有想过 当数据量很大的时候,使用for循环嵌套找出不一样的对象,需要多久... -
js比较两个数组对象,取出key相同的并push进同一数组
2020-07-18 16:41:24首先我们来mock两个对象数组: previousList = [ { dbtime: "02", e: 100, kk: 200 },{ dbtime: "05", e: 20, kk: 100 }],currentList = [{ dbtime: "02", e: 50, kk: 600 },{ dbtime: "05", e: ... -
List中根据对象字段快速查找对象
2020-09-02 11:00:20import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List;... * List中根据对象字段快速查找对象 * @date 2020-05-12 9:47 */ public class FSearchUtil { private StringBuffer. -
数组对象查找某一个对象
2020-04-27 10:04:30这里写自定义目录标题数组对象查找某一个对象 数组对象查找某一个对象 一个数组中有多个对象 每个对象都有一个或多个相同的属性 如何根据对象的属性值找到该数组中存在的某个对象 let _acData = acData.find(x =>... -
JVM的Class对象的存储位置和作用
2019-06-14 09:17:24JVM的Class对象的存储位置和作用 (2018-03-25 16:50:16) 分类: Java 在弄清这个问题前必须的明白类型信息和JVM方法区。 类型信息是一个java类的描述信息(class mate),classloader加载一个类时从class文件中提取出来... -
Python快速编程入门课后习题答案
2019-11-24 13:03:43(4)、相比python2.x版本,python3.x版本在异常方面有很多改变: •在python2.x版本,所有类型的对象都是直接被抛出的,但是,在python3.x版本中,只有继承自BaseException的对象才可以被抛出。 •在python2.x版本中... -
多级嵌套对象数组-根据最里层id找出它所属的每层父级
2020-04-21 15:54:422,假如这个id是数组第二层某项的,则获取第二层的数组,并且获取这项所在第一层的哪项 3,假如这个id是数组第三层某项的,则获取第三层的数组,并且获取这项所在第二层的哪项和所在的第一层的哪项 就是这么拗口,... -
java1.8使用stream流快速拿到集合中的最大值或者最小值或者某个对象的案例分析
2020-03-27 22:15:30直接上代码,截图如下: package com.itmuch.cloud.test; import java.util.ArrayList; import java.util.List; /** * @author:mischen * @date:2020/3/27 22:02 ... public static void ma... -
面向对象在生活中世界
2016-12-15 17:13:26面向对象是怎么来的,是由面向过程演变而来,所以我们要对面向过程有一个简单的了解,最常见的面向过程理解就是想用有什么就创建一个什么来用,没有太多的全面思考,而面向对象的出现就是为了修复面向过程的种种不足... -
Java中创建对象的六个步骤 细分后(new关键字)对象头详细介绍
2020-07-16 22:31:39要看的懂对象的创建过程,首先你得有对Java虚拟机和Java基础以及JUC很是熟悉,比如类的加载过程,CAS、多线程、JVM的GC等等 首先好看一个图,我大概会根据图中的内容来分享这六个步骤(其实几个步骤不重要,只要包括... -
Java引用对象
2018-12-11 10:09:03在写了15年C/C++之后,我于1999年开始写Java。借助指针切换(pointer handoffs)等编码实践或者Purify等工具,我认为自己对C风格的内存管理已经得心应手了,甚至已经不记得上次发生内存泄露是什么时候了。所以起初我... -
超硬核!十万字c++题,让你秒杀老师和面试官(上)
2021-04-21 10:46:15而在C++中,初始化时在执行相关代码时才会进行初始化,主要是由于C++引入对象后,要进行初始化必须执行相应构造函数和析构函数,在构造函数或析构函数中经常会需要进行某些程序中需要进行的特定操作,并非简单地... -
【小技巧】 java里快速遍历、打印数组和map 等对象
2018-03-21 10:50:15然而在java中,基本参数类型还好,引用参数类型,如果没有重新tostring方法是 就经常打应对象地址。。。wtk 我要看里面的值啊,对象地址有何用。所以一般做法,对象要写个重tostring方法, 打印而数组、map等时,... -
Java对象在哪里创建
2017-04-08 18:38:011,寄存器,存取速度最快,在cpu里面 2,堆栈,地址引用放栈里,对象放堆里,Java中的引用可以理解为c中的指针 3,堆,方面灵活但是缺点是比较耗内存(何时清除?) 4,静态区,存一些static的数据,程序执行时... -
AD查找相似对象使用进阶
2018-06-21 11:43:33本文介绍如何使用AD查找相似对象的功能,来快速修改丝印,线宽和封装。 1 快速修改丝印 可以使用查找相似对象的方式来快捷修改。 放置板子的名字和投板日期。其它需要说明的事项。 例如,快速调整丝印的...