作用:比较新旧数组,得到新增的元素,删除的元素,更新的元素
1 public class DiffUtil { 2 @Data 3 @Accessors(chain = true) 4 public static class DiffResult<T> { 5 /** 6 * 新增对象列表 7 */ 8 private List<T> addedList; 9 /** 10 * 修改后的对象列表 11 */ 12 private List<T> changedList; 13 /** 14 * 已删除对象列表 15 */ 16 private List<T> deletedList; 17 } 18 19 /** 20 * 对比两个List的元素 21 * <p> 22 * 如果 baseList 的元素在 targetList 中存在 PrimaryKey 相等的元素并且 elementComparator 比较结果不相等,则将修改后的值添加到changedList列表中; 23 * 如果 baseList 的元素在 targetList 中不存在,将baseList中的元素添加到deletedList中; 24 * 如果 targetList 的元素在 baseList 中不存在,将targetList中的元素添加到addedList中; 25 * <p> 26 * complexity: O(n) 27 * 28 * @param baseList 基础List(原来的List) 29 * @param targetList 目标List(最新的List) 30 * @param elementComparator 元素比较器 31 * @param primaryKeyExtractor 主键选择器 32 * @param <T> 33 * @return 对比结果 34 */ 35 public static <T> DiffResult<T> diffList(List<T> baseList, 36 List<T> targetList, 37 @NotNull Function<T, Object> primaryKeyExtractor, 38 @NotNull Comparator<T> elementComparator) { 39 40 DiffResult<T> checkResult = checkEmptyAndReturn(baseList, targetList); 41 if (checkResult != null) { 42 return checkResult; 43 } 44 45 Map<Object,T> baseMap = new HashMap<>(4096); 46 for(T base : baseList){ 47 Object key = primaryKeyExtractor.apply(base); 48 baseMap.put(key,base); 49 } 50 51 List<T> addedList = new ArrayList<>(); 52 List<T> changedList = new ArrayList<>(); 53 List<T> deletedList = new ArrayList<>(); 54 55 //找出新增的 和需要更新的 56 for (T target : targetList) { 57 Object key = primaryKeyExtractor.apply(target); 58 T base = baseMap.get(key); 59 if(base == null){ 60 addedList.add(target); 61 }else{ 62 baseMap.remove(key); 63 if (elementComparator.compare(base, target) != 0) { 64 changedList.add(target); 65 } 66 } 67 } 68 69 //剩余的就是需要删除的 70 Set<Map.Entry<Object, T>> entrySet = baseMap.entrySet(); 71 if(CollectionUtils.isNotEmpty(entrySet)){ 72 for(Map.Entry<Object, T> entry:entrySet){ 73 deletedList.add(entry.getValue()); 74 } 75 } 76 77 return new DiffResult<T>() 78 .setAddedList(addedList) 79 .setChangedList(changedList) 80 .setDeletedList(deletedList); 81 } 82 83 84 /** 85 * 检查baseList 和 targetList 为empty(null||size==0)的情况 86 * 87 * @param baseList 88 * @param targetList 89 * @param <T> 90 * @return 91 */ 92 private static <T> DiffResult<T> checkEmptyAndReturn(List<T> baseList, List<T> targetList) { 93 94 if (CollectionUtils.isEmpty(baseList) && CollectionUtils.isEmpty(targetList)) { 95 return new DiffResult<T>() 96 .setAddedList(null) 97 .setChangedList(null) 98 .setDeletedList(null); 99 } 100 101 if (CollectionUtils.isEmpty(baseList) && CollectionUtils.isNotEmpty(targetList)) { 102 return new DiffResult<T>() 103 .setAddedList(targetList) 104 .setChangedList(null) 105 .setDeletedList(null); 106 } 107 108 if (CollectionUtils.isNotEmpty(baseList) && CollectionUtils.isEmpty(targetList)) { 109 return new DiffResult<T>() 110 .setAddedList(null) 111 .setChangedList(null) 112 .setDeletedList(baseList); 113 } 114 return null; 115 } 116 117 @Data 118 @AllArgsConstructor 119 public static class User { 120 private Integer id; 121 private String userName; 122 private String realName; 123 }
1 案列: 2 @Test 3 void test04(){ 4 List<DiffUtil.User> baseList=new ArrayList<>(); 5 List<DiffUtil.User> targetList=new ArrayList<>(); 6 DiffUtil.User user=new DiffUtil.User(1,"a","b"); 7 DiffUtil.User user1=new DiffUtil.User(2,"a","b"); 8 baseList.add(user); 9 baseList.add(user1); 10 DiffUtil.User user2=new DiffUtil.User(3,"a","b"); 11 DiffUtil.User user3=new DiffUtil.User(4,"a","b"); 12 DiffUtil.User user4=new DiffUtil.User(1,"abb","bbbb"); 13 14 targetList.add(user4); 15 targetList.add(user2); 16 targetList.add(user3); 17 // 主键选择器 18 Function<DiffUtil.User,Object> function=mbi-> mbi.getId(); 19 // 元素比较器 20 DiffUtil.DiffResult<DiffUtil.User> result= DiffUtil.diffList(baseList,targetList,function,new Comparator<DiffUtil.User>(){ 21 @Override 22 public int compare(DiffUtil.User o1, DiffUtil.User o2) { 23 int i = 0; 24 // 自定義比較規則,帥選出更新的元素 25 if (o1.getUserName().equals(o2.getUserName())){ 26 i=0; 27 }else { 28 i=1; 29 } 30 return i; 31 32 } 33 }); 34 35 System.out.println(result.getAddedList()); 36 System.out.println(result.getDeletedList()); 37 System.out.println(result.getChangedList()); 38 39 // 通過以下操作可得到最終更新後的新數組 40 baseList.addAll(result.getAddedList()); 41 baseList.removeAll(result.getDeletedList()); 42 baseList.forEach(mbi->{ 43 for (DiffUtil.User obj:result.getChangedList()){ 44 if (mbi.getId()==obj.getId()){ 45 mbi.setRealName(obj.getRealName()); 46 mbi.setUserName(obj.getUserName()); 47 } 48 } 49 }); 50 System.out.println(baseList); 51 }