List集合的并集、交集、差集以及源码

其实list集合在平时开发中使用的比较多,下面我们来看看list集合的并集、交集、差集以及源码

1、并集:

jdk api 中并集的实现有两种方式:(1)、在原集合的末尾追加(2)、在原集合的指定位置开始追加

(1)、

addAll(Collection<? extendsE> c)
          按照指定 collection 的迭代器所返回的元素顺序,将该 collection 中的所有元素添加到此列表的尾部。

(2)、

addAll(int index, Collection<? extends E> c)
          从指定的位置开始,将指定 collection 中的所有元素插入到此列表中。

源码:ArrayList 集合 并集

 // 两个集合并集的实现 
    public boolean addAll(Collection<? extends E> c) {
		// 集合转化为数组
        Object[] a = c.toArray();
		// 数组大小
        int numNew = a.length;
		//判断原来集合的大小能否存下两个集合在的元素,如果能存放则存放,如果不能存放则扩容
        ensureCapacityInternal(size + numNew);  // Increments modCount
		//将a数组拷贝到elementData数组中
        System.arraycopy(a, 0, elementData, size, numNew);
        size += numNew;
        return numNew != 0;
    }

其中用到了两个数组赋值工具:

1、Arrays.copyOf(elementData, newCapacity);  将旧数组中的数据复制到新数组中去

2、System.arraycopy(Object src, int srcPos,Object dest, int destPos, int length)
          从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束,即src 被复制数组,srcPos 起始索引 ,length要复制数组的长度,dest原有数组destpos 指定位置开始添加。



源码:ArrayList集合 交集

 //交集
    public boolean retainAll(Collection<?> c) {
      // 这里调用的时候是true
     return batchRemove(c, 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.
			// 将elementData 中的从r开始的元素复制到 elementData的w开始的位置,复制的长度就是size-r
            if (r != size) {
                System.arraycopy(elementData, r,
                                 elementData, w,
                                 size - r);
                w += size - r;
            }
			// 删除 不相等哪些数据,w是从0开始 w的值也就是两个集合交集元素的个数
            if (w != size) {
                for (int i = w; i < size; i++)
                    elementData[i] = null;
                modCount += size - w;
                size = w;
                modified = true;
            }
        }
        return modified;
    }

(1)、使用集合的contains()方法判断这个元素在集合中是否存在存在返回true 不存在返回false

(2)、同样适用 System.arraycopy(elementData, r, elementData, w, size - r);  方法将elementData 中的从r开始的元素复制到elementData 中的w开始的位置,复制的长度是size-r


源码:ArrayList 集合差集


	 //差集
    public boolean removeAll(Collection<?> c) {
        return batchRemove(c, false);
    }


    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++)
                //遍历获取原来数组中的每一个元素和现在元素进行对比如果不相等也就是从elementData 中去除和c中一样的元素
                if (c.contains(elementData[r]) == complement)
                    // elementData数组中有而c中没有的则保存到elementData 数组中
                    elementData[w++] = elementData[r];
        } finally {
            // Preserve behavioral compatibility with AbstractCollection,
            // even if c.contains() throws.
            // 将elementData 中的从r开始的元素复制到 elementData的w开始的位置,复制的长度就是size-r
            if (r != size) {
                System.arraycopy(elementData, r,
                                 elementData, w,
                                 size - r);
                w += size - r;
            }
            // 删除 不相等哪些数据,w是从0开始 w的值也就是elementData中元素的个数-c中和elementData中相同的元素的个数
            if (w != size) {
                for (int i = w; i < size; i++)
                    elementData[i] = null;
                modCount += size - w;
                size = w;
                modified = true;
            }
        }
        return modified;
    }


差集 和交集的适用了同一个工具方法,一个是相同的留下,一个是相同的去掉其他思路都一样!



你可能感兴趣的:(List集合的并集、交集、差集以及源码)