JAVA中DIFF算法實現(xiàn)
更新時間:2023年07月03日 14:46:02 作者:編程路上的wdm
本文主要介紹了JAVA中DIFF算法實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
首先看一下我的文件結構
1.EnumType 類
public enum EnumType { ADD("ADD"),MODIFIED("MODIFIED"), DELETED("DELETED"); //創(chuàng)建私有變量 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 { ? ? @Data ? ? public 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 ? ? @AllArgsConstructor ? ? public static class User { ? ? ? ? private Integer id; ? ? ? ? private String userName; ? ? ? ? private String address; ? ? ? ? private String email; ? ? } }
4.ObjectComparator類
public class ObjectComparator<T> implements Comparator<T> { ? ? @Override ? ? public int compare(T o1, T o2) { ? ? ? ? // 反射來動態(tài)獲取對象的屬性 ? ? ? ? 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 { @Test public 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); } }
到此這篇關于JAVA中DIFF算法實現(xiàn)的文章就介紹到這了,更多相關JAVA DIFF算法內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:
相關文章
程序包org.springframework.boot不存在的問題解決
本文主要介紹了程序包org.springframework.boot不存在的問題解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2024-09-09springboot打war包部署到外置tomcat容器的方法
這篇文章主要介紹了springboot]打war包部署到外置tomcat容器,在這需要注意的是在boot-launch.war在tomcat?webapps目錄里面解壓到boot-launch文件夾,感興趣的朋友跟隨小編一起看看吧2022-04-04