com.flyfish.oauth.common.sync.support.CollectionComparator Maven / Gradle / Ivy
/**
* CollectionComparator.java com.bibenet.cedp.utils.service
*
* ****************************************************************************
* Change Log
*
* 1. wangyu create me at 2016年10月20日16:27 for class DESC. 2.
* ****************************************************************************
* Copyright (c) 2016, www.bibenet.com All Rights Reserved.O(∩_∩)O
*/
package com.flyfish.oauth.common.sync.support;
import com.flyfish.oauth.common.Function;
import com.flyfish.oauth.utils.ContainUtils;
import org.apache.commons.collections4.CollectionUtils;
import java.util.*;
/**
*
CollectionComparator
* 对象比较实用工具类
* 用途:
* 1.用来根据指定字段求出对象集合的差并补集
* 2.用于比较对象列表,并定义比较器逐级比较
* 3.提供各种集合封装,便于取出想要的结果集
* 特性:
* 1.命名空间保护,不可手动初始化
* 2.懒加载机制,按需分配资源
* 3.提供对象复用方法changeTarget
* 4.提供回调机制,传入比较器求出不同集(高效率)
* 用法:
* 1.不带比较器的初始化工厂
* CollectionComparator util = CollectionComparator.newInstance(
* originList,newList, ReflectDataUtil.getMethod(Project.class)
* );
* 2.带比较器的初始化工厂
* CollectionComparator util = CollectionComparator.newInstanceWithComparator(
* originList,newList, ReflectDataUtil.getMethod(Project.class),
* new Comparator() { ${compare}}
* );
* 取出变更的内容
* util.changedKeys();
*
* @author wangyu
*/
public class CollectionComparator {
private List origin;
private List copy;
private List> keyMethod;
private Comparator comparator;
/* 前者变为后者删除的集合 */
private List deleted;
/* 前者变为后者增加的集合 */
private List added;
/* 前者变为后者增加的Code集合 */
private Set addedKeys;
/* 前者变为后者删除的Code集合 */
private Set deletedKeys;
/* 前者转变为后者不变的集合 */
private Set remainedKeys;
/* 前者与后者key相同,内容不同的Code集合 */
private Set changedKeys;
/* 前者转变为后者不变和变更的Map */
private Map resultMap;
/* 原始数据key组装的map */
private Map originMap;
/* 新数据key组装的map */
private Map newMap;
/* 额外绑定数据 */
private Object bind;
private CollectionComparator() {
}
private CollectionComparator(List origin, List copy, List> keyMethods, Comparator comparator) {
this.origin = origin;
this.copy = copy;
this.keyMethod = keyMethods;
this.comparator = comparator;
handler();
}
//泛型多态化
public static CollectionComparator newInstance(List origin, List copy, Function keyMethod) {
return newInstanceWithComparator(origin, copy, keyMethod, null);
}
public static CollectionComparator newInstance(List origin, List copy, List> keyMethods) {
return newInstanceWithComparator(origin, copy, keyMethods, null);
}
public static CollectionComparator newInstanceWithComparator(List origin, List copy, Function keyMethod, Comparator comparator) {
return new CollectionComparator<>(origin, copy, Collections.singletonList(keyMethod), comparator);
}
public static CollectionComparator newInstanceWithComparator(List origin, List copy, List> keyMethods, Comparator comparator) {
return new CollectionComparator<>(origin, copy, keyMethods, comparator);
}
public CollectionComparator changeTarget(List origin, List copy) {
this.origin = origin;
this.copy = copy;
deleted = added = null;
addedKeys = deletedKeys = remainedKeys = changedKeys = null;
originMap = newMap = null;
bind = resultMap = null;
handler();
return this;
}
/**
* 前者变为后者增加的集合
*
* @return 结果集
*/
public List added() {
if (added == null) {
added = ContainUtils.listWithKeys(newMap, addedKeys());
}
return added;
}
/**
* 前者变为后者删除的集合
*
* @return 结果集
*/
public List deleted() {
if (deleted == null) {
deleted = ContainUtils.listWithKeys(originMap, deletedKeys());
}
return deleted;
}
/**
* 前者变为后者增加的Code集合
*
* @return key的集合
*/
public Set addedKeys() {
if (addedKeys == null) {
//新添加的
addedKeys = new HashSet<>(newMap.keySet());
addedKeys.removeAll(originMap.keySet());
}
return addedKeys;
}
/**
* 前者变为后者删除的Code集合
*
* @return key的集合
*/
public Set deletedKeys() {
if (deletedKeys == null) {
//已经删除的
deletedKeys = new HashSet<>(originMap.keySet());
deletedKeys.removeAll(newMap.keySet());
}
return deletedKeys;
}
@SuppressWarnings("unchecked")
public List remainedOriginList() {
if (null == resultMap().get("originList")) {
resultMap.put("originList", ContainUtils.listWithKeys(originMap, remainedKeys()));
}
return (List) resultMap().get("originList");
}
@SuppressWarnings("unchecked")
public List remainedNewList() {
if (null == resultMap().get("newList")) {
resultMap.put("newList", ContainUtils.listWithKeys(newMap, remainedKeys()));
}
return (List) resultMap().get("newList");
}
@SuppressWarnings("unchecked")
public List changedOriginList() {
if (null == resultMap().get("changeOriginList")) {
resultMap.put("changeOriginList", ContainUtils.listWithKeys(originMap, changedKeys()));
}
return (List) resultMap().get("changeOriginList");
}
@SuppressWarnings("unchecked")
public List changedNewList() {
if (null == resultMap().get("changeNewList")) {
resultMap.put("changeNewList", ContainUtils.listWithKeys(newMap, changedKeys()));
}
return (List) resultMap().get("changeNewList");
}
/**
* 前者转变为后者不变的集合
*
* @return key的集合
*/
public Set remainedKeys() {
if (remainedKeys == null) {
//未增删过的对象
remainedKeys = new HashSet<>(originMap.keySet());
remainedKeys.addAll(newMap.keySet());
remainedKeys.removeAll(deletedKeys());
remainedKeys.removeAll(addedKeys());
remainedKeys.removeAll(changedKeys());
}
return remainedKeys;
}
public Set changedKeys() {
if (changedKeys == null) {
changedKeys = new HashSet<>();
if (comparator != null) {
Set remainedKeys = new HashSet<>(originMap.keySet());
remainedKeys.addAll(newMap.keySet());
remainedKeys.removeAll(deletedKeys());
remainedKeys.removeAll(addedKeys());
for (K key : remainedKeys) {
if (comparator.compare(originMap.get(key), newMap.get(key)) != 0) {
changedKeys.add(key);
}
}
}
}
return changedKeys;
}
/**
* 前者转变为后者不变的集合
*
* @return key的集合
*/
public Map originMap() {
return originMap;
}
/**
* 前者转变为后者不变的集合
*
* @return key的集合
*/
public Map newMap() {
return newMap;
}
/**
* 前者转变为后者不变的Map(正本)
*
* @return map
*/
@SuppressWarnings("unchecked")
public Map remainedOriginMap() {
if (null == resultMap().get("origin")) {
resultMap.put("origin", ContainUtils.putAllWithKeys(new HashMap(), remainedKeys(), originMap));
}
return (Map) resultMap().get("origin");
}
/**
* 前者转变为后者不变的Map(副本)
*
* @return map
*/
@SuppressWarnings("unchecked")
public Map remainedNewMap() {
if (null == resultMap().get("copy")) {
resultMap.put("copy", ContainUtils.putAllWithKeys(new HashMap(), remainedKeys(), newMap));
}
return (Map) resultMap().get("copy");
}
/**
* 前者转变为后者改变的Map(正本)
*
* @return map
*/
@SuppressWarnings("unchecked")
public Map changedOriginMap() {
if (null == resultMap().get("change_origin")) {
resultMap.put("change_origin", ContainUtils.putAllWithKeys(new HashMap(), changedKeys(), originMap));
}
return (Map) resultMap().get("change_origin");
}
/**
* 前者转变为后者改变的Map(副本)
*
* @return map
*/
@SuppressWarnings("unchecked")
public Map changedNewMap() {
if (null == resultMap().get("change_copy")) {
resultMap.put("change_copy", ContainUtils.putAllWithKeys(new HashMap(), changedKeys(), newMap));
}
return (Map) resultMap().get("change_copy");
}
public Object getBind() {
return bind;
}
public void bind(Object bind) {
this.bind = bind;
}
/**
* 两个集合内容是否相等(针对数据)
*
* @return 布尔
*/
public boolean isEqual() {
return CollectionUtils.isEmpty(addedKeys()) && CollectionUtils.isEmpty(deletedKeys()) && CollectionUtils.isEmpty(changedKeys());
}
private void handler() {
originMap = new HashMap<>();
newMap = new HashMap<>();
if (origin != null && copy != null) {
for (T item : origin) {
originMap.put(getKey(item), item);
}
for (T item : copy) {
newMap.put(getKey(item), item);
}
}
}
@SuppressWarnings("unchecked")
private K getKey(T item) {
if (1 == keyMethod.size()) {
return keyMethod.get(0).apply(item);
}
StringBuilder key = new StringBuilder();
for (Function method : keyMethod) {
key.append(method.apply(item));
}
return (K) key.toString();
}
private Map resultMap() {
if (resultMap == null) {
resultMap = new HashMap<>();
}
return resultMap;
}
}