原创

【集合】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

正文到此结束
广告是为了更好的提供数据服务
本文目录