zoukankan      html  css  js  c++  java
  • 集合交集、差集工具类

    1.业务背景

    • 在日常开发中,有时会遇到需要对比两个集合来计算出两个集合的交集、差集。以此来决定之后对数据库的insert、delete、update操作。例如,在一些管理系统中配置管理员列表后,如果需要更新管理员列表,需要从前端获取新管理员列表,比对数据库中旧有的管理员列表,然后决定哪些集合需要insert入数据库,哪些需要从数据库中delete。
    • 以上是业务背景的简单介绍,但是如果是一些数据规模比较小或者修改不是很频繁的业务场景,则不需要比对集合,完全可以将旧有数据全部删除,然后将新数据insert入库中。

    2.工具类介绍

    2.1 主工具类

    package cn.sun.utils;
    
    import org.springframework.util.CollectionUtils;
    
    import java.util.HashSet;
    import java.util.List;
    import java.util.Set;
    import java.util.stream.Collectors;
    
    /**
     * @author : ssk
     * @date : 2020/11/22
     *
     * @desc 集合比对
     */
    public class CollectionCompareUtil {
    
        /**
         * 比对新老集
         *
         * @param oldTargetList 旧有集合——一般从数据库中查出来
         * @param newTargetList 新集合——  一般根据前端数据组装
         * @param compareSelection 比对标识:需要比对两个结合的交集、差集选项。默认全为true,置为true表示需要计算该类型。详见CompareFlag描述
         * @param <T> 传入T需按需重写equal()、hashCode()方法
         * @return
         */
        public static <T> CollectionCompareResult compare(List<T> oldTargetList, List<T> newTargetList, CompareSelection compareSelection) {
            if (CollectionUtils.isEmpty(oldTargetList) || CollectionUtils.isEmpty(newTargetList)) {
                throw new RuntimeException("入参错误");
            }
    
            // 自身去重
            Set<T> oleTargetSet = new HashSet<>(oldTargetList);
            Set<T> newTargetSet = new HashSet<>(newTargetList);
    
            CollectionCompareResult collectionCompareResult = new CollectionCompareResult();
    
            // 需更新
            if (compareSelection.getUpdateFlag()) {
                collectionCompareResult.setUpdateTargetList(oleTargetSet.stream().filter(newTargetSet::contains).collect(Collectors.toList()));
            }
    
            // 需新增
            if (compareSelection.getAddFlag()) {
                collectionCompareResult.setAddTargetList(newTargetSet.stream().filter(item -> !oleTargetSet.contains(item)).collect(Collectors.toList()));
            }
    
            // 需删除
            if (compareSelection.getDeleteFlag()) {
                collectionCompareResult.setDeleteTargetList(oleTargetSet.stream().filter(item -> !newTargetSet.contains(item)).collect(Collectors.toList()));
            }
    
            return collectionCompareResult;
        }
    
    }
    
    
    • 对需要比对的实体按需重写equal()和hashCode()方法
    package cn.sun.test.bean;
    
    import lombok.Builder;
    import lombok.Data;
    
    import java.util.Objects;
    
    /**
     * @author : ssk
     * @date : 2020/11/22
     */
    @Data
    @Builder
    public class User {
    
        private String id;
    
        private String name;
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
    
            if (o == null || getClass() != o.getClass()) return false;
    
            User user = (User) o;
            return Objects.equals(id, user.id);
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(id);
        }
    }
    
    

    2.2 需比对类型封装

    package cn.sun.utils;
    
    /**
     * @author : ssk
     * @date : 2020/11/22
     *
     * 对两个集合交集,差集选择
     */
    public class CompareSelection {
    
        /**
         * 差集(newList-oldList)标识
         */
        private Boolean addFlag = true;
    
        /**
         * 交集(newList:oldList)标识
         */
        private Boolean updateFlag = true;
    
        /**
         * 差集(oldList-newList)标识
         */
        private Boolean deleteFlag = true;
    
        public Boolean getAddFlag() {
            return addFlag;
        }
    
        public void setAddFlag(Boolean addFlag) {
            this.addFlag = addFlag;
        }
    
        public Boolean getUpdateFlag() {
            return updateFlag;
        }
    
        public void setUpdateFlag(Boolean updateFlag) {
            this.updateFlag = updateFlag;
        }
    
        public Boolean getDeleteFlag() {
            return deleteFlag;
        }
    
        public void setDeleteFlag(Boolean deleteFlag) {
            this.deleteFlag = deleteFlag;
        }
    }
    
    

    2.3 比对结果封装

    package cn.sun.utils;
    
    
    import java.util.List;
    
    /**
     * @author : ssk
     * @date : 2020/11/22
     */
    public class CollectionCompareResult<T> {
    
        /**
         * 需新增列表
         */
        private List<T> addTargetList;
    
        /**
         * 需删除列表
         */
        private List<T> deleteTargetList;
    
        /**
         * 需更新列表
         */
        private List<T> updateTargetList;
    
        public List<T> getAddTargetList() {
            return addTargetList;
        }
    
        public void setAddTargetList(List<T> addTargetList) {
            this.addTargetList = addTargetList;
        }
    
        public List<T> getDeleteTargetList() {
            return deleteTargetList;
        }
    
        public void setDeleteTargetList(List<T> deleteTargetList) {
            this.deleteTargetList = deleteTargetList;
        }
    
        public List<T> getUpdateTargetList() {
            return updateTargetList;
        }
    
        public void setUpdateTargetList(List<T> updateTargetList) {
            this.updateTargetList = updateTargetList;
        }
    }
    
    

    2.4 简单总结

    • 使用该工具类需要注意以下几点:
      • 按需重写集合中实体的equal()、hashCode()两个方法
      • 按需定义CompareSelection。如果没有定义则默认计算三种类型。

    3.工具类简单测试

    package cn.sun.test.utils;
    
    import cn.sun.test.bean.User;
    import cn.sun.utils.CollectionCompareResult;
    import cn.sun.utils.CollectionCompareUtil;
    import cn.sun.utils.CompareSelection;
    import org.junit.Test;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @author : ssk
     * @date : 2020/11/22
     */
    public class CollectionCompareUtilTest {
    
        @Test
        public void test() {
            User user1 = User.builder().id("1").name("赤犬").build();
            User user2 = User.builder().id("2").name("青雉").build();
            User user3 = User.builder().id("3").name("黄猿").build();
            User user4 = User.builder().id("4").name("藤虎").build();
            User user5 = User.builder().id("5").name("绿牛").build();
    
            List<User> oldTargetList = new ArrayList<>();
            oldTargetList.add(user1);
            oldTargetList.add(user2);
            oldTargetList.add(user3);
    
            List<User> newTargetList = new ArrayList<>();
            newTargetList.add(user3);
            newTargetList.add(user4);
            newTargetList.add(user5);
    
            CollectionCompareResult compareResult = CollectionCompareUtil.compare(oldTargetList, newTargetList, new CompareSelection());
            System.out.println("海军大将变动---未变动大将:" + compareResult.getUpdateTargetList()
                    + "离职大将:" + compareResult.getDeleteTargetList()
                    + "新上任大将:" + compareResult.getAddTargetList());
        }
    }
    
    
    • output:
    海军大将变动---未变动大将:[User(id=3, name=黄猿)]
      离职大将:[User(id=1, name=赤犬), User(id=2, name=青雉)]
      新上任大将:[User(id=4, name=藤虎), User(id=5, name=绿牛)]
    
    
  • 相关阅读:
    Proj THUDBFuzz Paper Reading: PMFuzz: Test Case Generation for Persistent Memory Programs
    入围 WF 后训练记
    算法竞赛历程
    2021 多校 杭电 第十场
    2021 多校 杭电 第九场
    2021 多校 牛客 第十场
    2021 多校 牛客 第九场
    2021 多校 杭电 第八场
    2021 多校 杭电 第六场
    2021 多校 杭电 第七场
  • 原文地址:https://www.cnblogs.com/riders/p/14021625.html
Copyright © 2011-2022 走看看