Browse Source

增加对比新老数组的 C/U/D 对象

YunaiV 1 year ago
parent
commit
222d1cf69b

+ 5 - 0
yudao-framework/yudao-common/pom.xml

@@ -133,6 +133,11 @@
             <artifactId>transmittable-thread-local</artifactId>
         </dependency>
 
+        <!-- Test 测试相关 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+        </dependency>
     </dependencies>
 
 </project>

+ 44 - 5
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtils.java

@@ -6,12 +6,11 @@ import cn.hutool.core.map.MapUtil;
 import com.google.common.collect.ImmutableMap;
 
 import java.util.*;
-import java.util.function.BinaryOperator;
-import java.util.function.Function;
-import java.util.function.Predicate;
-import java.util.function.Supplier;
+import java.util.function.*;
 import java.util.stream.Collectors;
 
+import static java.util.Arrays.asList;
+
 /**
  * Collection 工具类
  *
@@ -20,7 +19,7 @@ import java.util.stream.Collectors;
 public class CollectionUtils {
 
     public static boolean containsAny(Object source, Object... targets) {
-        return Arrays.asList(targets).contains(source);
+        return asList(targets).contains(source);
     }
 
     public static boolean isAnyEmpty(Collection<?>... collections) {
@@ -190,6 +189,46 @@ public class CollectionUtils {
         return func.apply(mapData);
     }
 
+    /**
+     * 对比老、新两个列表,找出新增、修改、删除的数据
+     *
+     * @param oldList 老列表
+     * @param newList 新列表
+     * @param sameFunc 对比函数,返回 true 表示相同,返回 false 表示不同
+     *                 注意,same 是通过每个元素的“标识”,判断它们是不是同一个数据
+     * @return [新增列表、修改列表、删除列表]
+     */
+    public static <T> List<List<T>> diffList(Collection<T> oldList, Collection<T> newList,
+                                             BiFunction<T, T, Boolean> sameFunc) {
+        List<T> createList = new LinkedList<>(newList); // 默认都认为是新增的,后续会进行移除
+        List<T> updateList = new ArrayList<>();
+        List<T> deleteList = new ArrayList<>();
+
+        // 通过以 oldList 为主遍历,找出 updateList 和 deleteList
+        for (T oldObj : oldList) {
+            // 1. 寻找是否有匹配的
+            T foundObj = null;
+            for (Iterator<T> iterator = createList.iterator(); iterator.hasNext(); ) {
+                T newObj = iterator.next();
+                // 1.1 不匹配,则直接跳过
+                if (!sameFunc.apply(oldObj, newObj)) {
+                    continue;
+                }
+                // 1.2 匹配,则移除,并结束寻找
+                iterator.remove();
+                foundObj = newObj;
+                break;
+            }
+            // 2. 匹配添加到 updateList;不匹配则添加到 deleteList 中
+            if (foundObj != null) {
+                updateList.add(foundObj);
+            } else {
+                deleteList.add(oldObj);
+            }
+        }
+        return asList(createList, updateList, deleteList);
+    }
+
     public static boolean containsAny(Collection<?> source, Collection<?> candidates) {
         return org.springframework.util.CollectionUtils.containsAny(source, candidates);
     }

+ 64 - 0
yudao-framework/yudao-common/src/test/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtilsTest.java

@@ -0,0 +1,64 @@
+package cn.iocoder.yudao.framework.common.util.collection;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.function.BiFunction;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * {@link CollectionUtils} 的单元测试
+ */
+public class CollectionUtilsTest {
+
+    @Data
+    @AllArgsConstructor
+    private static class Dog {
+
+        private Integer id;
+        private String name;
+        private String code;
+
+    }
+
+    @Test
+    public void testDiffList() {
+        // 准备参数
+        Collection<Dog> oldList = Arrays.asList(
+                new Dog(1, "花花", "hh"),
+                new Dog(2, "旺财", "wc")
+        );
+        Collection<Dog> newList = Arrays.asList(
+                new Dog(null, "花花2", "hh"),
+                new Dog(null, "小白", "xb")
+        );
+        BiFunction<Dog, Dog, Boolean> sameFunc = (oldObj, newObj) -> {
+            boolean same = oldObj.getCode().equals(newObj.getCode());
+            // 如果相等的情况下,需要设置下 id,后续好更新
+            if (same) {
+                newObj.setId(oldObj.getId());
+            }
+            return same;
+        };
+
+        // 调用
+        List<List<Dog>> result = CollectionUtils.diffList(oldList, newList, sameFunc);
+        // 断言
+        assertEquals(result.size(), 3);
+        // 断言 create
+        assertEquals(result.get(0).size(), 1);
+        assertEquals(result.get(0).get(0), new Dog(null, "小白", "xb"));
+        // 断言 update
+        assertEquals(result.get(1).size(), 1);
+        assertEquals(result.get(1).get(0), new Dog(1, "花花2", "hh"));
+        // 断言 delete
+        assertEquals(result.get(2).size(), 1);
+        assertEquals(result.get(2).get(0), new Dog(2, "旺财", "wc"));
+    }
+
+}