【集合】Java 集合的交集(AnB)、(去重)并集(AuB)、差集(A-B)、交集的补集 (AuB) - (AnB) 的计算
最近项目中用到了一些数学集合和数据模型处理。在这简单回忆一下初中中学学到的一些数学问题。
交集(AnB)、并集(AuB)、差集(A-B)、交集的补集 (AuB) - (AnB)
前言
集合是我们在日常开发设计中用到的最多的数据结构。如果要对多个集合进行差异或差错处理的话,两个独立的for循环会极大的增加代码复杂度和未来的理解成本,使用集合的交集、并集和差集能够更便捷的帮助我们去解决这个问题。
对于一个结果其实有很多种方式可以达到我们的目的。在这里我们不探究有多少种变种实现,仅直接以代码的形式,来展现jdk,jdk stream, apache的解决方式。
接口
概览
- 集合的交集(AnB) intersect
- 集合的并集(AuB) union
- 集合的差集(A-B) diff
- 交集的补集 (AuB) - (AnB) disjunction
定义接口
package com.yueny.study.jdk.collection.union;
import java.util.List;
/**
* 集合的交集(AnB)、并集(AuB)、差集(A-B)、交集的补集 (AuB) - (AnB)、去重并集 计算
*/
public interface ICollectionUnoinService {
/**
* 求2个集合的交集(AnB)
*
* @param ls
* @param compare
* @param <T>
* @return
*/
<T> List<T> intersect(List<T> ls, List<T> compare);
/**
* 求2个集合的并集(AuB), 不排序,不去重
*
* @param ls
* @param compare
* @param <T>
* @return
*/
<T> List<T> union(List<T> ls, List<T> compare);
/**
* 求 ls 和 compare 的差集, 即ls 中有,但 compare 中没有的
*
* @param ls
* @param compare
* @return
*/
<T> List<T> diff(List<T> ls, List<T> compare);
/**
* 交集的补集 (AuB) - (AnB), 既并集 减 交集
*/
<T> List<T> disjunction(List<T> ls, List<T> compare);
}
jdk 实现
package com.yueny.study.jdk.collection.union;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* jdk list 的操作
*/
public class JdkList implements ICollectionUnoinService {
public static void main(String[] args) {
JdkList jdk = new JdkList();
List<String> list1 = new ArrayList<String>();
list1.add("1");
list1.add("2"); //
list1.add("3"); //
list1.add("5");
list1.add("6");
List<String> list2 = new ArrayList<String>();
list2.add("2"); //
list2.add("3"); //
list2.add("7");
list2.add("8");
// 差集 (list1 - list2)
List<String> lt1 = jdk.diff(list1, list2);
System.out.println("差集 (list1 - list2)");
System.out.println(lt1);
// 差集 (list2 - list1)
List<String> lt2 = jdk.diff(list2, list1);
System.out.println("差集 (list2 - list1)");
System.out.println(lt2);
// 交集 intersection
List<String> lt3 = jdk.intersect(list1, list2);
System.out.println("交集 intersection");
System.out.println(lt3);
// 并集
List<String> listAll = jdk.union(list1, list2);
System.out.println("并集");
System.out.println(listAll);
// 交集的补集
List<String> disjunction = jdk.disjunction(list1, list2);
System.out.println("交集的补集 (AuB) - (AnB)");
System.out.println(disjunction);
}
@Override
public <T> List<T> diff(List<T> ls, List<T> compare) {
/**
* 构造一个相同大小的空集合
*
* new Object[ls.size()] 的意义在于直接分配相应的内存空间, 直接 new ArrayList(ls.size()) 是不行的
*/
List<T> list = new ArrayList(Arrays.asList(new Object[ls.size()]));
// 将 ls 的数据克隆至 list。
Collections.copy(list, ls);
// 移除 compare 数据
list.removeAll(compare);
return list;
}
@Override
public <T> List<T> disjunction(List<T> ls, List<T> compare) {
List<T> union = union(ls, compare);
union.removeAll(intersect(ls, compare));
return union;
}
@Override
public <T> List<T> intersect(List<T> ls, List<T> compare) {
List<T> list = new ArrayList(Arrays.asList(new Object[ls.size()]));
Collections.copy(list, ls);
list.retainAll(compare);
return list;
}
@Override
public <T> List<T> union(List<T> ls, List<T> compare) {
//并集, 去重
List<T> list = new ArrayList(Arrays.asList(new Object[ls.size()]));
//将ls的值拷贝一份到list中
Collections.copy(list, ls);
list.removeAll(compare);
list.addAll(compare);
return list;
}
}
jdk stream 实现
package com.yueny.study.jdk.collection.union;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* jdk Stream 的操作
*/
public class JdkStream implements ICollectionUnoinService {
public static void main(String[] args) {
JdkStream jdk = new JdkStream();
List<String> list1 = new ArrayList<String>();
list1.add("1");
list1.add("2"); //
list1.add("3"); //
list1.add("5");
list1.add("6");
List<String> list2 = new ArrayList<String>();
list2.add("2"); //
list2.add("3"); //
list2.add("7");
list2.add("8");
// 差集 (list1 - list2)
List<String> lt1 = jdk.diff(list1, list2);
System.out.println("差集 (list1 - list2)");
System.out.println(lt1);
// 差集 (list2 - list1)
List<String> lt2 = jdk.diff(list2, list1);
System.out.println("差集 (list2 - list1)");
System.out.println(lt2);
// 交集 intersection
List<String> lt3 = jdk.intersect(list1, list2);
System.out.println("交集 intersection");
System.out.println(lt3);
// 并集
List<String> listAll = jdk.union(list1, list2);
System.out.println("并集");
System.out.println(listAll);
// 交集的补集
List<String> disjunction = jdk.disjunction(list1, list2);
System.out.println("交集的补集 (AuB) - (AnB)");
System.out.println(disjunction);
// 去重并集
}
@Override
public <T> List<T> intersect(List<T> ls, List<T> compare) {
return ls.stream().filter(item -> compare.contains(item)).collect(Collectors.toList());
}
@Override
public <T> List<T> union(List<T> ls, List<T> compare) {
//并集, 但不去重
List<T> listAll = ls.parallelStream().collect(Collectors.toList());
List<T> listAll2 = compare.parallelStream().collect(Collectors.toList());
listAll.addAll(listAll2);
return listAll;
}
@Override
public <T> List<T> diff(List<T> ls, List<T> compare) {
return ls.stream().filter(item -> !compare.contains(item)).collect(Collectors.toList());
}
@Override
public <T> List<T> disjunction(List<T> ls, List<T> compare) {
List<T> union = union(ls, compare);
union.removeAll(intersect(ls, compare));
return union;
}
}
Apache 实现
package com.yueny.study.jdk.collection.union;
import org.apache.commons.collections4.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
/**
* apache 的操作
*/
public class Apache implements ICollectionUnoinService {
public static void main(String[] args) {
Apache apache = new Apache();
List<String> list1 = new ArrayList<String>();
list1.add("1");
list1.add("2"); //
list1.add("3"); //
list1.add("5");
list1.add("6");
List<String> list2 = new ArrayList<String>();
list2.add("2"); //
list2.add("3"); //
list2.add("7");
list2.add("8");
// 差集 (list1 - list2)
List<String> lt1 = apache.diff(list1, list2);
System.out.println("差集(A-B) (list1 - list2)");
System.out.println(lt1);
// 差集 (list2 - list1)
List<String> lt2 = apache.diff(list2, list1);
System.out.println("差集(A-B) (list2 - list1)");
System.out.println(lt2);
// 交集 intersection
List<String> lt3 = apache.intersect(list1, list2);
System.out.println("交集(AnB) intersection");
System.out.println(lt3);
// 并集
List<String> listAll = apache.union(list1, list2);
System.out.println("并集(AuB)");
System.out.println(listAll);
// 交集的补集
List<String> disjunction = apache.disjunction(list1, list2);
System.out.println("交集的补集 (AuB) - (AnB)");
System.out.println(disjunction);
// 去重并集
}
@Override
public <T> List<T> diff(List<T> ls, List<T> compare) {
//集合相减
return new ArrayList<>(CollectionUtils.subtract(ls, compare));
}
@Override
public <T> List<T> disjunction(List<T> ls, List<T> compare) {
// 交集的补集
return new ArrayList<>(CollectionUtils.disjunction(ls, compare));
}
@Override
public <T> List<T> intersect(List<T> ls, List<T> compare) {
//交集
return new ArrayList<>(CollectionUtils.intersection(ls, compare));
}
@Override
public <T> List<T> union(List<T> ls, List<T> compare) {
//并集, 去重
return new ArrayList<>(CollectionUtils.union(ls, compare));
}
}
~ end
正文到此结束
热门推荐
相关文章
广告是为了更好的提供数据服务