zoukankan      html  css  js  c++  java
  • 快速从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的方式

  • 相关阅读:
    Heritrix源码分析(十) Heritrix中的Http Status Code(Http状态码)(转)
    Heritrix源码分析(九) Heritrix的二次抓取以及如何让Heritrix抓取你不想抓取的URL
    Heritrix源码分析(八) Heritrix8个处理器(Processor)介绍(转)
    HTML 的 iframe 元素
    CSS 选择器及其优先级
    在触屏设备中拖动 overflow 元素
    关于博客园博问标签的自我实现
    ABAP中读取EXCEL中不同的SHEET数据
    创建表索引
    Call Transaction
  • 原文地址:https://www.cnblogs.com/zhanh247/p/12109114.html
Copyright © 2011-2022 走看看