import java.util.*
/**
* 计算多个集合的并集、差集、交集
* @author qianmo
*/
public class SetOperation<T> {
private List<Long> listTags
private List<List<T>> setList = new ArrayList<>()
private Map<T,Long> resultSet = new HashMap<>()
public SetOperation(List<T>... setList) {
this.setList.addAll(List.of(setList))
int setNumber = setList.length
this.listTags = createTag(setNumber)
}
private List<Long> createTag(int setNumber) {
List<Long> listTags = new ArrayList<>()
Long tag = 1L
for (int i = 0
tag = tag << 1
listTags.add(tag)
}
return listTags
}
public SetOperation calculate(){
for (int i = 0
Long tag = listTags.get(i)
List<T> set = setList.get(i)
for (int j = 0
T key = set.get(j)
Long mark = resultSet.get(key)
mark = mark == null ? 0L : mark
resultSet.put(key,mark | tag)
}
}
return this
}
public Long calculateTag(int... setIndexes){
// 计算tag
Long tag = 0L
for (int index : setIndexes) {
tag = tag | listTags.get(index)
}
return tag
}
//获取交集
public List<T> intersection(int... setIndexes){
Long tag = calculateTag(setIndexes)
List<T> set = new ArrayList<>()
Set<Map.Entry<T, Long>> entrySet = resultSet.entrySet()
Iterator<Map.Entry<T, Long>> iterator = entrySet.iterator()
while (iterator.hasNext()){
Map.Entry<T, Long> entry = iterator.next()
if ((entry.getValue() & tag) == tag){
set.add(entry.getKey())
}
}
return set
}
//获取并集
public List<T> union(int... setIndexes){
Long tag = calculateTag(setIndexes)
List<T> set = new ArrayList<>()
Set<Map.Entry<T, Long>> entrySet = resultSet.entrySet()
Iterator<Map.Entry<T, Long>> iterator = entrySet.iterator()
while (iterator.hasNext()){
Map.Entry<T, Long> entry = iterator.next()
if ((entry.getValue() & tag) > 0) {
set.add(entry.getKey())
}
}
return set
}
//获取差集
public List<T> differenceSet(int[] xIndexes,int[] yIndexes){
Long xtag = calculateTag(xIndexes)
Long ytag = calculateTag(yIndexes)
List<T> set = new ArrayList<>()
Set<Map.Entry<T, Long>> entrySet = resultSet.entrySet()
Iterator<Map.Entry<T, Long>> iterator = entrySet.iterator()
while (iterator.hasNext()){
Map.Entry<T, Long> entry = iterator.next()
if ((entry.getValue() & xtag) > 0 && (ytag & (entry.getValue())) != ytag) {
set.add(entry.getKey())
}
}
return set
}
public static void main(String[] args) {
List<String> list1 = Arrays.asList("a", "b", "c", "d", "e", "f")
List<String> list2 = Arrays.asList("a", "b", "c", "d", "q", "t")
List<String> list3 = Arrays.asList("a", "b", "c", "d", "w", "y")
List<String> list4 = Arrays.asList("a", "b", "c", "d", "r", "u")
SetOperation<String> setOperation = new SetOperation<>(list1,list2,list3,list4).calculate()
List<String> union = setOperation.union(0, 1,2)
System.out.println(union)
int[] x = {0,1,3}
int[] y = {2}
List<String> difference = setOperation.differenceSet(x, y)
System.out.println(difference)
List<String> intersection = setOperation.intersection(0, 1,2,3)
System.out.println(intersection)
}
}