All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.cshencode.util.list.ListCompareUtil Maven / Gradle / Ivy

There is a newer version: 2.1.2-RELEASE
Show newest version
package io.github.cshencode.util.list;


import net.sf.cglib.beans.BeanCopier;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * * 数据对比器
 *
 * @author css
 * @param  实体类的类型
 * @param  实体类id的类型
 */
public class ListCompareUtil {
    private final static ConcurrentHashMap, BeanCopier> BEAN_COPIER_MAP = new ConcurrentHashMap<>();

    private final Collection oldenList;
    private final Collection newlyList;
    /**
     * 数组回调
     */
    private Consumer> updateListConsumer;
    private Consumer> insertListConsumer;
    private Consumer> idRemoveConsumer;
    /**
     * 单个回调
     */
    private Function updateOneFunction;
    private Function insertOneFunction;
    private Function idOneFunction;
    private Consumer> removeListConsumer;
    private Function idGetter;

    private ListCompareUtil(Collection oldenList, Collection newlyList, Function idGetter) {
        this.oldenList = Optional.ofNullable(oldenList).orElse(new ArrayList<>());
        this.newlyList = Optional.ofNullable(newlyList).orElse(new ArrayList<>());
        this.idGetter = idGetter;
    }

    public ListCompareUtil idGetter(Function idGetter) {
        this.idGetter = idGetter;
        return this;
    }

    /**
     * 当有更新数据发生时
     * @param updateListConsumer
     * @return
     */
    public ListCompareUtil whenUpdate(Consumer> updateListConsumer) {
        this.updateListConsumer = updateListConsumer;
        return this;
    }

    /**
     * 当有新数据发生时
     * @param insertListConsumer
     * @return
     */
    public ListCompareUtil whenInsert(Consumer> insertListConsumer) {
        this.insertListConsumer = insertListConsumer;
        return this;
    }

    /**
     * 当有删除数据发生时
     * @param idRemoveConsumer
     * @return
     */
    public ListCompareUtil whenRemove(Consumer> idRemoveConsumer) {
        this.idRemoveConsumer = idRemoveConsumer;
        return this;
    }

    public ListCompareUtil whenUpdateOne(Function updateOneFunction) {
        this.updateOneFunction = updateOneFunction;
        return this;
    }

    public ListCompareUtil whenInsertOne(Function insertOneFunction) {
        this.insertOneFunction = insertOneFunction;
        return this;
    }

    public ListCompareUtil whenRemoveOne(Function idOneFunction) {
        this.idOneFunction = idOneFunction;
        return this;
    }

    public ListCompareUtil whenRemoveEntity(Consumer> removeListConsumer) {
        this.removeListConsumer = removeListConsumer;
        return this;
    }

    /**
     * 构建比较器
     *
     * @param oldenList
     * @param newlyList
     * @param idGetter
     * @param 
     * @param 
     * @return 返回构建的工具类
     */
    public static  ListCompareUtil builder(Collection oldenList,
                                                       Collection newlyList,
                                                       Function idGetter) {
        return new ListCompareUtil(oldenList, newlyList, idGetter);
    }

    /**
     * 开始对比新老数据
     */
    public void compare() {
        if (oldenList.isEmpty() && newlyList.isEmpty()) {
            return;
        }

        List insertList = new ArrayList<>();
        List tmpNewlyList = new ArrayList<>();
        for (Entity newEntity : newlyList) {
            if (idGetter.apply(newEntity) == null) {
                insertList.add(newEntity);
            } else {
                tmpNewlyList.add(newEntity);
            }
        }
        //通过ID映射数据
        Map oldenMap = this.oldenList.stream().collect(Collectors.toMap(idGetter, Function.identity(), (f, s) -> f, LinkedHashMap::new));
        Map newlyMap = tmpNewlyList.stream().collect(Collectors.toMap(idGetter, Function.identity(), (f, s) -> f, LinkedHashMap::new));

        Set oldenKeys = oldenMap.keySet();
        Set newlyKeys = newlyMap.keySet();

        //获取需要更新的数据, oldenMap中存在newlyMap中的key,则需要更新
        //获取需要新增的数据,newlyMap中不存在与oldenMap中的,则需要添加
        //获取需要删除的数据,oldenMap中不存在与newlyMap中的,则需要删除
        List updateList = new ArrayList<>();
        Set idRemoves = new HashSet<>();
        List removeList = new ArrayList<>();

        oldenKeys.forEach(oldenKey -> {
            //旧key存在于新key中,则需要更新
            if (newlyKeys.contains(oldenKey)) {
                Entity olden = oldenMap.get(oldenKey);
                Entity newly = newlyMap.get(oldenKey);
                BeanCopier beanCopier = BEAN_COPIER_MAP.computeIfAbsent(newly.getClass(), key ->
                        BeanCopier.create(key, key, false));
                beanCopier.copy(newly, olden, null);
                updateList.add(newly);
            } else {//不存在则需要删除
                idRemoves.add(oldenKey);
                removeList.add(oldenMap.get(oldenKey));
            }
        });

        newlyKeys.forEach(newlyKey -> {
            //旧key不包含则需要新增
            if (!oldenKeys.contains(newlyKey)) {
                insertList.add(newlyMap.get(newlyKey));
            }
        });

        // 回调更新
        if (!updateList.isEmpty()) {
            if (updateOneFunction != null) {
                for (Entity updateEntity : updateList) {
                    updateOneFunction.apply(updateEntity);
                }
            } else if (updateListConsumer != null) {
                updateListConsumer.accept(updateList);
            }
        }

        // 回调插入
        if (!insertList.isEmpty()) {
            if (insertOneFunction != null) {
                for (Entity insertEntity : insertList) {
                    insertOneFunction.apply(insertEntity);
                }
            } else if (insertListConsumer != null) {
                insertListConsumer.accept(insertList);
            }
        }

        // 回调删除
        if (!idRemoves.isEmpty()) {
            if (idOneFunction != null) {
                for (IdType id : idRemoves) {
                    idOneFunction.apply(id);
                }
            } else if (idRemoveConsumer != null) {
                idRemoveConsumer.accept(idRemoves);
            } else if (removeListConsumer != null) {
                removeListConsumer.accept(removeList);
            }
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy