【java】Collection求差集

转载请注明出处:http://blog.csdn.net/u012250875/article/details/78203365

1.如何求差集

Collection系列的集合求差集十分简单,仅仅调用Collection中提供的removeAll方法即可。
A-B(A差B)求法:A.removeAll(B),A-B的结果存放在A中

2.removeAll方法解读

2.1关于removeAll的返回值
求A-B时,由于结果最后存放在集合A中,如果集合A的元素与求差集之前比发生变化,返回值为true,否则为false

2.2 removeAll和retainAll
removeAll和retainAll的具体定义如下:

boolean removeAll(Collection<?> c);

boolean retainAll(Collection<?> c)

二者定义一致,入参相同,返回值意义相同,都表示集合元素是否发生变化。惊人的相似啊。我们如果看一看Collection的实现类,如ArrayList的源码,会发现removeAll和retainAll两个方法的实现都几乎一致,唯独调用batchRemove方法时第二参数一个是false,一个是true,观察batchRemove方法,发现该方法根据第二个参数,如果为true则记录B集合有的且A集合有的元素,即为交集;如果为false则记录A集合中有而B集合中没有的元素,即为A-B;而返回值对应的变量modified,该值在w != size(w为结果集的个数,size为A集合元素个数)时才会为true。源码如下:

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

    public boolean retainAll(Collection<?> c) {
         Objects.requireNonNull(c);
         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.
            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;
    }

3. 封装方法

有时候求差集,并不想破坏原有的集合,并且可能是想用一个list和一个set进行求差集,虽然工具方法返回值是个List,但是List转Set还是很方便,构造方法即可。实现如下

    /**
     * @author puyf
     * @Description:求集合a-b
     * @param a 
     * @param b
     * @return 返回A-B的结果
     */
    public static <T,K extends Collection<? extends T>> List<T> sub(K a,K b){
        List<T> result = new ArrayList<>();
        if(a!=null){
            result = new ArrayList<>(a);
            result.removeAll(b);
        }
        return result;
    }

使用如下:

    public static void main(String[] args) {
        List<Number> list1 = new ArrayList<>(Arrays.asList(new Integer[]{5,6,7}));
        Set<Integer> set = new HashSet<>(Arrays.asList(new Integer[]{5,6}));
        System.out.println("{5,6,7}差{5,6}的结果为"+sub(list1,set));
    }

    //结果
    {5,6,7}差{5,6}的结果为[7]

更多集合工具类,集合操作(点击查看

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值