快速从2个List集合中找出相同/不同元素

Posted zhanh247

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了快速从2个List集合中找出相同/不同元素相关的知识,希望对你有一定的参考价值。

最近刚好涉及到从2个不同集合中找出不同的元素的需求,以下为测试代码

1、利用 apache collection 工具内中的方法,附上坐标

<dependency>
    <groupId>commons-collections</groupId>
    <artifactId>commons-collections</artifactId>
    <version>3.2.1</version>
</dependency>

collection 工具包中给出出了2个比较方便的工具方法

1、找共同的元素 org.apache.commons.collections.ListUtils.retainAll(Collection, Collection) 附上源码如下

    public static List removeAll(Collection collection, Collection remove) {
        List list = new ArrayList();
        for (Iterator iter = collection.iterator(); iter.hasNext();) {
            Object obj = iter.next();
            if (remove.contains(obj) == false) {
                list.add(obj);
            }
        }
        return list;
    }

 

2、找出不同的元素 org.apache.commons.collections.ListUtils.removeAll(Collection, Collection) 附上源码如下

    public static List retainAll(Collection collection, Collection retain) {
        List list = new ArrayList(Math.min(collection.size(), retain.size()));

        for (Iterator iter = collection.iterator(); iter.hasNext();) {
            Object obj = iter.next();
            if (retain.contains(obj)) {
                list.add(obj);
            }
        }
        return list;
    }

附上测试 demo 代码

    public static void main(String[] args) {
        // 生成集合1
        List<Integer> list1 = Lists.newArrayList();
        for (int i = 0; i < 100000; i++) {
            list1.add(i);
        }
        // 生成集合 2
        List<Integer> list2 = Lists.newArrayList();
        for (int i = 0; i < 100001; i++) {
            list2.add(i);
        }
        long start = System.currentTimeMillis();
        // 开始分离
        List<Integer> list = ListUtils.removeAll(list2, list1);
        long end = System.currentTimeMillis();
        System.out.println(list);
        System.out.println(end - start);
        // 总执行次数 100000*100001
    }

执行结果如下

[100000]
4027

通过源码可以看出 集合迭代过程执行了100000*100001 次,随着数据量增加,速度将越来越慢,所以有了如下的优化方案, 付上代码

    public static void main(String[] args) {
        // 生成集合1
        List<Integer> list1 = Lists.newArrayList();
        for (int i = 0; i < 100000; i++) {
            list1.add(i);
        }
        // 生成集合2
        List<Integer> list2 = Lists.newArrayList();
        for (int i = 0; i < 100001; i++) {
            list2.add(i);
        }
        long start = System.currentTimeMillis();
        //开始分离
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        for (Integer integer : list2) {
            map.put(integer, 1);
        }
        for (Integer integer : list1) {
            map.put(integer, 2);
        }
        List<Integer> list3 = new ArrayList<Integer>();
        Set<Entry<Integer, Integer>> entrySet = map.entrySet();
        for (Entry<Integer, Integer> entry : entrySet) {
            Integer value = entry.getValue();
            if (Objects.equals(1, value)) {
                list3.add(entry.getKey());
            }
        }
        //结束分离
        long end = System.currentTimeMillis();
        System.out.println(list3);
        System.out.println(end - start);
        //总执行次数 100000+100001+100001
    }

执行结果

[100000]
33

差距非常明显,且我们分析执行次数可以看出,通过map执行迭代次数为100000+100001+100001 迭代次数减少很多,速度自然上来了

总结:当数据量不大的情况下,通过ListUtils.removeAll 的方式还是非常推荐,毕竟不用自己造轮子,但是如果数据量达到百万级以上时,推荐使用Map的方式

以上是关于快速从2个List集合中找出相同/不同元素的主要内容,如果未能解决你的问题,请参考以下文章

Java高效找出两个大数据量List集合中的不同元素

高效的找出两个List中的不同元素

给定两个列表,怎么找出他们相同的元素和不同的元素?

从两个List集合里找到相同部分和不同部分

Java 2 个 List 集合数据求并补集操作

C#, 从一个 List 中选出最大值并用红色字体显示的写法。