可用于数据对接时,筛选出新旧数据中有差异的对象;此方法需要引入HUTOOL工具
<!--Hutool是一个小而全的Java工具类库-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.16</version>
</dependency>
此方法只是用于思路展示;
大数据情况下,建议不要使用此反射方法,直接复制思路,替换list,快很多;不要问为什么,问就是反射;
附带用20000条数据下反射与不用的对比耗时
package com.ambition.hisLink.utils;
import cn.hutool.core.builder.EqualsBuilder;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.StopWatch;
import cn.hutool.core.lang.Console;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.util.*;
import java.util.concurrent.TimeUnit;
@Slf4j
public class ListCompareUtils {
/**
*
* (此方法只是用于思路展示;
* 大数据情况下,建议不要使用此方法,直接复制思路,替换list,快很多;有大量反射;
* 附带用大量反射与少用的对比耗时)
*
* 两个List比较;新数据与旧数据进行对比,旧数据与新数据中通过指定唯一字段值进行比对,判断旧数据其他字段中哪些需要修改;
* 以及新数据中哪些为新增数据,旧数据哪些需要删除
* @param newData 新数据
* @param oldData 旧数据
* @param notCompare 不需要判断修改的字段名(null时,判断所有字段)
* @param only 新旧数据比对的字段名(唯一字段值所在字段)
* @param <T>
* @return
*/
public static <T> Map<String, List<T>> getListCompare(List<T> newData, List<T> oldData, String[] notCompare, String[] only) {
Map<String, List<T>> map = new HashMap();
List<T> updateList = new ArrayList<>();
for (int i = newData.size()-1; i >=0 ; i--) {
for (int j = oldData.size()-1; j >=0 ; j--) {
T t = newData.get(i);
T t1 = oldData.get(j);
if (judgeOnly(only, t, t1)) {
if (!EqualsBuilder.reflectionEquals(t,t1,notCompare)) {
//当有修改时,加入updateList中,跳出旧oldData,继续遍历newData;
updateList.add(t);
}
newData.remove(i);
oldData.remove(j);
break;
}
}
}
log.info("insertList ->{},updateList ->{},deleteList->{}",newData.size(),updateList.size(),oldData.size());
map.put("insertList", newData);
map.put("updateList", updateList);
map.put("deleteList", oldData);
return map;
}
/**
* 判断是否满足比较条件
*
* @param only 需要满足相等的字段名
* @param one 对象1
* @param two 对象2
* @param <T>
* @return
*/
private static <T> boolean judgeOnly(String[] only, T one, T two) {
for (String onlyStr : only) {
Object onlyValue = ReflectUtil.getFieldValue(one, onlyStr);
Object onlyValue1 = ReflectUtil.getFieldValue(two, onlyStr);
if ((!ObjectUtil.isBasicType(onlyValue) && !(onlyValue instanceof String) )
|| (!ObjectUtil.isBasicType(onlyValue1) && !(onlyValue1 instanceof String) )
|| !ObjectUtil.equal(onlyValue, onlyValue1)) {
return false;
}
}
return true;
}
public static void main(String[] args) {
List<DemoPojo> value1 = new ArrayList<>();
List<DemoPojo> value2 = new ArrayList<>();
for (int i = 0; i < 20000; i++) {
DemoPojo pdaExecutionDrug = new DemoPojo();
pdaExecutionDrug.setBedno(i + "");
pdaExecutionDrug.setPatname("zhangshan"+i);
pdaExecutionDrug.setCureno("1234");
value1.add(pdaExecutionDrug);
}
for (int i = 2; i < 25000; i++) {
DemoPojo pdaExecutionDrug = new DemoPojo();
pdaExecutionDrug.setBedno(i + "");
pdaExecutionDrug.setPatname("zhangshan"+(i<15000?i : i+1));
pdaExecutionDrug.setCureno( "123");
value2.add(pdaExecutionDrug);
}
StopWatch stopWatch = DateUtil.createStopWatch();
stopWatch.start("用反射");
Map<String, List<DemoPojo>> listCompare = getListCompare(CollUtil.newArrayList(value1), CollUtil.newArrayList(value2), null, new String[]{"bedno"});
stopWatch.stop();
stopWatch.start("不用反射");
List<DemoPojo> update = new ArrayList<>();
for (int i = value1.size()-1; i >=0 ; i--) {
for (int j = value2.size()-1; j >=0 ; j--) {
DemoPojo t = value1.get(i);
DemoPojo t1 = value2.get(j);
if (t.getBedno().equals(t1.getBedno())) {
if (!EqualsBuilder.reflectionEquals(t,t1,"bedNo","cureno")){
update.add(t);
}
value1.remove(i);
value2.remove(j);
break;
}
}
}
log.info("insertList ->{},updateList ->{},deleteList->{}",value1.size(),update.size(),value2.size());
stopWatch.stop();
Console.log(stopWatch.prettyPrint(TimeUnit.SECONDS));
}
}
@Data
class DemoPojo {
private String bedno;
private String patname;
private String cureno;
}
2022-03-10 15:04:55.458 INFO --- [ main] c.a.hisLink.utils.ListCompareUtils : insertList ->2,updateList ->19998,deleteList->5000
2022-03-10 15:04:56.453 INFO --- [ main] c.a.hisLink.utils.ListCompareUtils : insertList ->2,updateList ->5000,deleteList->5000
StopWatch '': running time = 12 s
---------------------------------------------
s % Task name
---------------------------------------------
000000011 92% 用反射
000000000 08% 不用反射