JAVA的DIFF算法

news/2024/11/17 11:01:16/

首先看一下我的文件结构
文件目录结构

1.EnumType 类
public enum EnumType {ADD("ADD"),MODIFIED("MODIFIED"), DELETED("DELETED");//创建私有变量private String type;EnumType(String type) {this.type = type;}
}
2.OperationType类
public class OperationType {private static final EnumType ADD=EnumType.ADD;private static final EnumType MODIFIED=EnumType.MODIFIED;private static final EnumType REMOVED=EnumType.DELETED;
}
3.DiffListUtil类
public class DiffListUtil {@Datapublic static class TargetWrapper<T> {private T target;private EnumType type;public TargetWrapper(T target, EnumType type) {this.target = target;this.type = type;}// Getters and setters for target and type}@Data@Accessors(chain = true)public static class DiffResult<T> {private List<TargetWrapper<T>> allList;/*** 新增对象列表*/private List<TargetWrapper<T>> addedList;/*** 修改后的对象列表*/private List<TargetWrapper<T>> changedList;/*** 已删除对象列表*/private List<TargetWrapper<T>> deletedList;}/*** 对比两个List的元素* <p>* 如果 baseList 的元素在 targetList 中存在 PrimaryKey 相等的元素并且 elementComparator 比较结果不相等,则将修改后的值添加到changedList列表中;* 如果 baseList 的元素在 targetList 中不存在,将baseList中的元素添加到deletedList中;* 如果 targetList 的元素在 baseList 中不存在,将targetList中的元素添加到addedList中;* <p>* complexity: O(n)** @param baseList            基础List(原来的List)* @param targetList          目标List(最新的List)* @param elementComparator   元素比较器*primaryKeyExtractor* @param <T>* @return 对比结果*/public static <T> DiffResult<T> diffList(List<T> baseList,List<T> targetList,@NotNull Function<T, Object> primaryKeyExtractor,@NotNull Comparator<T> elementComparator) {DiffResult<T> checkResult = checkEmptyAndReturn(baseList, targetList);if (checkResult != null) {return checkResult;}Map<Object,T> baseMap = new HashMap<>(4096);for(T base : baseList){Object key = primaryKeyExtractor.apply(base);baseMap.put(key,base);}List<TargetWrapper<T>> addedList = new ArrayList<>();List<TargetWrapper<T>> changedList = new ArrayList<>();List<TargetWrapper<T>> deletedList = new ArrayList<>();List<TargetWrapper<T>> allList = new ArrayList<>();//找出新增的 和需要更新的for (T target : targetList) {Object key = primaryKeyExtractor.apply(target);T base = baseMap.get(key);if(base == null){addedList.add(new TargetWrapper<T>(target, EnumType.ADD));}else{baseMap.remove(key);if (elementComparator.compare(base, target) != 0) {changedList.add(new TargetWrapper<T>(target, EnumType.MODIFIED));}}}//剩余的就是需要删除的Set<Map.Entry<Object, T>> entrySet = baseMap.entrySet();if(CollUtil.isNotEmpty(entrySet)){for(Map.Entry<Object, T> entry:entrySet){deletedList.add(new TargetWrapper<T>(entry.getValue(), EnumType.DELETED));}}allList.addAll(addedList);addedList.addAll(changedList);addedList.addAll(deletedList);return new DiffResult<T>().setAddedList(addedList).setChangedList(changedList).setDeletedList(deletedList).setAllList(allList);}private static <T, V> void setFieldValue(T object, Function<? super T,V> fieldGetter, String value) {try {Field field = fieldGetter.getClass().getDeclaredField("value");field.setAccessible(true);field.set(fieldGetter.apply(object), value);} catch (NoSuchFieldException | IllegalAccessException e) {e.printStackTrace();}}/*** 检查baseList 和 targetList 为empty(null||size==0)的情况** @param baseList* @param targetList* @param <T>* @return*/private static <T> DiffResult<T> checkEmptyAndReturn(List<T> baseList, List<T> targetList) {if (CollUtil.isEmpty(baseList) && CollUtil.isEmpty(targetList)) {return new DiffResult<T>().setAddedList(null).setChangedList(null).setDeletedList(null);}if (CollUtil.isEmpty(baseList) && CollUtil.isNotEmpty(targetList)) {List<TargetWrapper<T>> wrapperTargetList = targetList.stream().map(t -> new TargetWrapper<>(t, EnumType.DELETED)).collect(Collectors.toList());return new DiffResult<T>().setAddedList(wrapperTargetList).setChangedList(null).setDeletedList(null);}if (CollUtil.isNotEmpty(baseList) && CollUtil.isEmpty(targetList)) {List<TargetWrapper<T>> wrapperBaseList = baseList.stream().map(t -> new TargetWrapper<>(t, EnumType.DELETED)).collect(Collectors.toList());return new DiffResult<T>().setAddedList(null).setChangedList(null).setDeletedList(wrapperBaseList);}return null;}@Data@AllArgsConstructorpublic static class User {private Integer id;private String userName;private String address;private String email;}
}
4.ObjectComparator类
public class ObjectComparator<T> implements Comparator<T> {@Overridepublic int compare(T o1, T o2) {// 反射来动态获取对象的属性Field[] fields = o1.getClass().getDeclaredFields();for (Field field : fields) {field.setAccessible(true);try {Object value1 = field.get(o1);Object value2 = field.get(o2);if (!isEqual(value1, value2)) {return compareValues(value1, value2);}} catch (IllegalAccessException e) {e.printStackTrace();}}return 0;}private int compareValues(Object value1, Object value2) {if (value1 == null && value2 == null) {return 0;}if (value1 == null) {return -1;}if (value2 == null) {return 1;}if (value1 instanceof Comparable && value2 instanceof Comparable) {return ((Comparable) value1).compareTo(value2);}return 0;}private boolean isEqual(Object value1, Object value2) {if (value1 == null && value2 == null) {return true;}if (value1 == null || value2 == null) {return false;}return value1.equals(value2);}
}
5.Test单元测试类
@RunWith(SpringRunner.class)
@SpringBootTest
public class DiffListUtilApplicationTest {@Testpublic void test1() {List<DiffListUtil.User> userList = new ArrayList<>();DiffListUtil diffListUtil = new DiffListUtil();userList.add(new DiffListUtil.User(11,"John","hunan","hunan@faw.com"));userList.add(new DiffListUtil.User(22,"Tom","jilin","jilin@faw.com"));List<DiffListUtil.User> userListAfter = new ArrayList<>();userListAfter.add(new DiffListUtil.User(33,"John","hunan","beijing@faw.com"));userListAfter.add(new DiffListUtil.User(22,"Wudaiming","hunan","hunan@faw.com"));Function<DiffListUtil.User, Object> primaryKeyExtractor = user -> user.getId();//Comparator<DiffListUtil.User> userComparator = Comparator//        .comparing(DiffListUtil.User::getId)//        .thenComparing(DiffListUtil.User::getUserName)//        .thenComparing(DiffListUtil.User::getAddress)//        .thenComparing(DiffListUtil.User::getEmail);ObjectComparator<DiffListUtil.User> userComparator = new ObjectComparator<>();DiffListUtil.DiffResult<DiffListUtil.User> userDiffResult = diffListUtil.diffList(userList, userListAfter, primaryKeyExtractor, userComparator);System.out.println(userDiffResult);}
}

http://www.ppmy.cn/news/687163.html

相关文章

兼容机

CPU AMD 羿龙IIX4 955(黑盒) (配一个散热器) 主板 技嘉GA-MA790XT-UD4P(rev. 1.0) 内存 金士顿 2GB DDR3 13332 硬盘 希捷 500GB 7200.12 32M 显卡 盈通 GTX260游戏高手 液显 LG W2242SP 机箱 酷冷至尊 毁灭者RC-K100 电源 航嘉600W多核F1电源 键鼠 …

计算机更改虚拟内存有用吗,虚拟内存有什么用?虚拟内存怎么设置,设置多少最好...

虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。 拟内存又叫虚拟存储器,电脑中所运行的程序均需经由…

项目设计:基于YOLO目标检测算法的安全帽/口罩/汽车/行人/交通标志...检测

本文将详细介绍YOLO目标检测算法&#xff0c;该算法支持各种目标检测&#xff0c;包括&#xff1a;安全帽、汽车、造价、交通标志......等。 其他毕业设计题目推荐参考&#xff1a; 毕业设计&#xff1a;电子/通信/计算机/物联网专业毕业设计选题参考&#xff08;嵌入式linux/…

炫龙P6笔记本搭建Windows 10+Ubuntu双系统

基本需求 做ROS机器人控制&#xff0c;可实现ros indigo安装&#xff0c;indigo兼容性好。可搭建深度学习Caffe框架。具备好的显卡。 电脑基本配置 炫龙P6 系列&#xff1a; X 系列 型号&#xff1a;毁灭者P6-780S2N 处理器CPU类型&#xff1a;第六代智能英特尔酷睿i7四核…

前端开发:JS中堆和栈的区别

前言 在前端实际开发中&#xff0c;有关JS原生的堆和栈也是很重要的点&#xff0c;关于底层和原理的掌握使用&#xff0c;尤其是在性能优化方面甚为重要。众所周知&#xff0c;JS的变量都是存放在内存中的&#xff0c;而且内存给变量开辟了两块区域&#xff0c;即堆区域和栈区域…

证明最小化负对数似然函数的学习策略等价于最小化 KL 散度的学习策略

首先&#xff0c;让我们定义一些符号&#xff1a; p data ( x ) p_{\text{data}}(x) pdata​(x)&#xff1a;真实数据的概率分布 p model ( x ; θ ) p_{\text{model}}(x; \theta) pmodel​(x;θ)&#xff1a;由参数 θ \theta θ 确定的模型的概率分布 D \mathcal{D} D&…

正版七日杀服务器存档,如何在网吧保存steam七日杀存档 | 手游网游页游攻略大全...

发布时间:2015-10-24 七日杀a13.6存档在哪 a13.6存档位置详解.a13.6是近期很热门的游戏,很多玩家不知道存档在哪?a13.6新版本存档位置改变了,有些玩家可能找不到游戏的存档目录,这里给大家介绍一下,希望对大 ... 标签: 七日杀 游戏攻略 游戏秘籍 发布时间:2015-12-14 七日杀…

【日语】动物名称日语单词集合

动物 dngw どうぶつ【动物】 doubutsu animals サッド 人 rn にんげん【人间】 ningen human being/person コン 马 m?? うま【马】 uma horse マー 斑马 b??nm?? しまうま【缟马】 shimauma zebra ラー 驴 l ろば【驴马】 roba ass/donkey 骡 lu らば【骡马】 raba mu…