• java 两个list 交集 并集 差集 去重复并集


    https://www.cnblogs.com/qlqwjy/p/9812919.html

    前提需要明白List是引用类型,引用类型采用引用传递。

      我们经常会遇到一些需求求集合的交集、差集、并集。例如下面两个集合:

    复制代码
            List<String> list1 = new ArrayList<String>();
            list1.add("A");
            list1.add("B");
    
            List<String> list2 = new ArrayList<String>();
            list2.add("B");
            list2.add("C");
    复制代码

     0.求差集

      例如,求List1中有的但是List2中没有的元素:

        public static void test3(List list1, List list2) {
            list1.removeAll(list2);
            System.out.println(list1);
        }

    结果:

    [A]

    查看ArrayList的removeAll的源码

        public boolean removeAll(Collection<?> c) {
            Objects.requireNonNull(c);
            return batchRemove(c, false);
        } 

    再查看batchRemove的源码:(如果传的第二个参数是false,保留差集;如果传的是true,保留的是交集)

    复制代码
        private boolean batchRemove(Collection<?> c, boolean complement) {
            final Object[] elementData = this.elementData;
            int r = 0, w = 0;
            boolean modified = false;
            try {
                for (; r < size; r++)
                    if (c.contains(elementData[r]) == complement)
                        elementData[w++] = elementData[r];
            } finally {
                // Preserve behavioral compatibility with AbstractCollection,
                // even if c.contains() throws.
                if (r != size) {
                    System.arraycopy(elementData, r,
                                     elementData, w,
                                     size - r);
                    w += size - r;
                }
                if (w != size) {
                    // clear to let GC do its work
                    for (int i = w; i < size; i++)
                        elementData[i] = null;
                    modCount += size - w;
                    size = w;
                    modified = true;
                }
            }
            return modified;
        }
    复制代码

      是重新定义elementData数组的元素,下面代码的作用是将本集合中不包含另一个集合的元素重新加入元素,以此实现删除的功能(注意上面调用的方法传的参数是false,也就是不包含的元素得以保留,实现差集的功能)

    if (c.contains(elementData[r]) == complement)
    elementData[w++] = elementData[r];

    1.求并集(不去重)---将一个集合全部加入另一个集合

        public static void test(List list1, List list2) {
            list1.addAll(list2);
            System.out.println(list1);
        }

    结果:

    [A, B, B, C]

    查看ArayList的addAll()源码是数组复制:

    复制代码
        public boolean addAll(Collection<? extends E> c) {
            Object[] a = c.toArray();
            int numNew = a.length;
            ensureCapacityInternal(size + numNew);  // Increments modCount
            System.arraycopy(a, 0, elementData, size, numNew);
            size += numNew;
            return numNew != 0;
        }
    复制代码

    再查看System的arraycopy发现是一个native方法(本地方法):---其实system类的好多方法都是native方法

        public static native void arraycopy(Object src,  int  srcPos,
                                            Object dest, int destPos,
                                            int length);

    2.求并集(去重)

      例如:求List1和List2的并集,并实现去重。

        思路是:先将list中与list2重复的去掉,之后将list2的元素全部添加进去。

        public static void test1(List list1, List list2) {
            list1.removeAll(list2);
            list1.addAll(list2);
            System.out.println(list1);
        }

    结果:

    [A, B, C]

    3.求交集

      例如:求List1和List2中都有的元素。

        public static void test2(List list1, List list2) {
            list1.retainAll(list2);
            System.out.println(list1);
        }

    结果:

    [B]

    在上面2的实验过程中,我们知道batchRemove(Collection,true)也是求交集,所以猜想  retainAll 内部应该是调用 batchRemove(Collection,true),查看ArrayList的源码如下:

        public boolean retainAll(Collection<?> c) {
            Objects.requireNonNull(c);
            return batchRemove(c, true);
        }
  • 相关阅读:
    计算机通信
    笔记0402
    笔记0414
    vb6 VS vb.net int数据类型
    jQuery好网站
    jQuery实现图片翻滚
    jQuery获取一组单选按钮的值
    Redhat安装、使用及服务器应用FAQ
    js判断变量是否赋值(存在)
    IDE 与SATA区别
  • 原文地址:https://www.cnblogs.com/yibuyi-123/p/14272930.html
Copyright © 2020-2023  润新知