cn.woodwhales.common.business.collection.CollectionMathResult Maven / Gradle / Ivy
package cn.woodwhales.common.business.collection;
import com.google.common.collect.Sets;
import cn.woodwhales.common.business.DataTool;
import java.util.List;
import java.util.Set;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;
import static com.google.common.base.Preconditions.checkNotNull;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptySet;
import static org.apache.commons.collections4.CollectionUtils.isEmpty;
import static org.apache.commons.collections4.CollectionUtils.isNotEmpty;
/**
* @author woodwhales on 2020-12-13 16:32
*/
public class CollectionMathResult implements CollectionMath {
/**
* 集合 A
*/
private List sourceList1;
/**
* 集合 B
*/
private List sourceList2;
/**
* 交集
*/
private Set> intersectionSet;
/**
* 并集
*/
private Set> unionSet;
/**
* 正差集 A - B
*/
private Set> positiveDifferenceSet;
/**
* 负差集 B - A
*/
private Set> negativeDifferenceSet;
/**
* 是否懒计算
* 是 - 每调用方法时计算
* 否 - new 实例完成时初始化
*/
private boolean lazyCompute;
/**
* 数据源集合 A 生成 set 集合的接口
*/
private Function keyFunction1;
/**
* 数据源集合 B 生成 set 集合的接口
*/
private Function keyFunction2;
/**
* 集合操作
* @param sourceList1 集合 A
* @param keyFunction1 集合 A 生成 set 的接口
* @param sourceList2 集合 B
* @param keyFunction2 集合 B 生成 set 的接口
* @param 要比较的数据类型
* @param 集合 A 的数据类型
* @param 集合 B 的数据类型
* @return CollectionMathResult
*/
public static CollectionMathResult compute(List sourceList1,
Function keyFunction1,
List sourceList2,
Function keyFunction2) {
return compute(sourceList1, keyFunction1, sourceList2, keyFunction2, false);
}
/**
* 集合操作
* @param sourceList1 集合 A
* @param keyFunction1 集合 A 生成 set 的接口
* @param sourceList2 集合 B
* @param keyFunction2 集合 B 生成 set 的接口
* @param lazyCompute 是否懒计算
* @param 要比较的数据类型
* @param 集合 A 的数据类型
* @param 集合 B 的数据类型
* @return CollectionMathResult
*/
public static CollectionMathResult compute(List sourceList1,
Function keyFunction1,
List sourceList2,
Function keyFunction2,
final boolean lazyCompute) {
CollectionMathResult collectionMathResult = new CollectionMathResult<>(sourceList1, keyFunction1,
sourceList2, keyFunction2,
lazyCompute);
if(lazyCompute) {
return collectionMathResult;
}
if(isNotEmpty(sourceList1) && isEmpty(sourceList2)) {
checkNotNull(keyFunction1, "keyFunction1 不允许为空");
Set> set = DataTool.toSet(sourceList1, source1 -> CollectionContainer.build(source1, keyFunction1));
collectionMathResult.setUnionSet(set)
.setPositiveDifferenceSet(set)
.setIntersectionSet(emptySet())
.setNegativeDifferenceSet(emptySet());
return collectionMathResult;
}
if(isEmpty(sourceList1) && isNotEmpty(sourceList2)) {
checkNotNull(keyFunction1, "keyFunction2 不允许为空");
Set> set = DataTool.toSet(sourceList2, source2 -> CollectionContainer.build(source2, keyFunction2));
collectionMathResult.setUnionSet(set)
.setPositiveDifferenceSet(emptySet())
.setIntersectionSet(emptySet())
.setNegativeDifferenceSet(set);
return collectionMathResult;
}
checkNotNull(keyFunction1, "keyFunction1 不允许为空");
checkNotNull(keyFunction1, "keyFunction2 不允许为空");
Set> set1 = DataTool.toSet(sourceList1, source1 -> CollectionContainer.build(source1, keyFunction1));
Set> set2 = DataTool.toSet(sourceList2, source2 -> CollectionContainer.build(source2, keyFunction2));
collectionMathResult.setPositiveDifferenceSet(Sets.difference(set1, set2))
.setNegativeDifferenceSet(Sets.difference(set2, set1))
.setUnionSet(Sets.union(set1, set2))
.setIntersectionSet(Sets.intersection(set1, set2));
return collectionMathResult;
}
public List getSourceList1() {
return sourceList1;
}
public List getSourceList2() {
return sourceList2;
}
@Override
public Set> getIntersectionSet() {
return getSet(intersectionSet, (set1, set2) -> Sets.intersection(set1, set2));
}
@Override
public Set getIntersectionKeySet() {
return getKeySet(intersectionSet, getIntersectionSet());
}
public CollectionMathResult setIntersectionSet(Set> intersectionSet) {
this.intersectionSet = intersectionSet;
return this;
}
@Override
public Set getUnionKeySet() {
return getKeySet(unionSet, getUnionSet());
}
@Override
public Set> getUnionSet() {
return getSet(unionSet, Sets::union);
}
public CollectionMathResult setUnionSet(Set> unionSet) {
this.unionSet = unionSet;
return this;
}
/**
* 正差集 A - B
* @return 正差集 A - B
*/
@Override
public Set getPositiveDifferenceKeySet() {
return getKeySet(positiveDifferenceSet, getPositiveDifferenceSet());
}
/**
* 正差集 A - B
* @return 正差集 A - B
*/
@Override
public List getPositiveDifferenceList() {
return getList(this.sourceList1, getPositiveDifferenceSet(), keyFunction1);
}
/**
* 正差集 A - B
* @return 正差集 A - B
*/
@Override
public Set> getPositiveDifferenceSet() {
return getSet(positiveDifferenceSet, (set1, set2) -> CollectionTool.difference(set1, set2));
}
/**
* 负差集 B - A
* @return 负差集 B - A
*/
@Override
public Set getNegativeDifferenceKeySet() {
return getKeySet(negativeDifferenceSet, getNegativeDifferenceSet());
}
/**
* 负差集 B - A
* @return 负差集 B - A
*/
@Override
public List getNegativeDifferenceList() {
return getList(this.sourceList2, getNegativeDifferenceSet(), keyFunction2);
}
/**
* 负差集 B - A
* @return 负差集 B - A
*/
@Override
public Set> getNegativeDifferenceSet() {
return getSet(negativeDifferenceSet, (set1, set2) -> CollectionTool.difference(set2, set1));
}
private static CollectionMathResult empty() {
return new CollectionMathResult()
.setIntersectionSet(emptySet())
.setUnionSet(emptySet())
.setPositiveDifferenceSet(emptySet())
.setNegativeDifferenceSet(emptySet());
}
private CollectionMathResult(List sourceList1,
Function keyFunction1,
List sourceList2,
Function keyFunction2,
final boolean lazyCompute) {
this.sourceList1 = sourceList1;
this.keyFunction1 = keyFunction1;
this.sourceList2 = sourceList2;
this.keyFunction2 = keyFunction2;
this.lazyCompute = lazyCompute;
}
private CollectionMathResult() {
}
private Set getKeySet(Set> set, Set> keySet) {
if (this.lazyCompute) {
return keySet.stream()
.map(CollectionFieldComparable::getDataKey)
.collect(Collectors.toSet());
}
return getKeySet(set);
}
private Set getKeySet(Set> set) {
return CollectionTool.toSet(set, CollectionFieldComparable::getDataKey);
}
private Set> getSet(Set> set,
BinaryOperator>> setFunction) {
if(!lazyCompute) {
return set;
}
Set> set1 = DataTool.toSet(sourceList1, source1 -> CollectionContainer.build(source1, keyFunction1));
Set> set2 = DataTool.toSet(sourceList2, source2 -> CollectionContainer.build(source2, keyFunction2));
return setFunction.apply(set1, set2);
}
private List getList(List list, Set> set, Function keyFunction) {
if(isEmpty(list)) {
return emptyList();
}
Set keySet = set.stream()
.map(CollectionFieldComparable::getDataKey)
.collect(Collectors.toSet());
return DataTool.filter(list, source -> keySet.contains(keyFunction.apply(source)));
}
public CollectionMathResult setPositiveDifferenceSet(Set> positiveDifferenceSet) {
this.positiveDifferenceSet = positiveDifferenceSet;
return this;
}
public CollectionMathResult setNegativeDifferenceSet(Set> negativeDifferenceSet) {
this.negativeDifferenceSet = negativeDifferenceSet;
return this;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy