• 【转】带你正确的使用List的retainAll方法求交集


    一、 retainAll 方法

    public boolean retainAll(Collection<?> c) {
            //调用自己的私有方法
            return batchRemove(c, true);
        }

    二、batchRemove 方法解析

    如果此 collection 由于调用而发生更改,则返回 true

    复制代码
    //集合A比较与集合B的交集
         private boolean batchRemove(Collection<?> c, boolean complement) {
                 //获得当前对象的所有元素
                final Object[] elementData = this.elementData;
                //w:标记两个集合公共元素的个数
                int r = 0, w = 0;
                //设置标志位
                boolean modified = false;
                try {
                    //遍历集合A
                    for (; r < size; r++)
                        //判断集合B中是否包含集合A中的当前元素
                        if (c.contains(elementData[r]) == complement)
                            //如果包含则直接保存。
                            elementData[w++] = elementData[r];
                } finally {
                    // 如果 c.contains() 抛出异常
                    if (r != size) {
                        //复制剩余的元素
                        System.arraycopy(elementData, r,
                                         elementData, w,
                                         size - r);
                        //w为当前集合A的length
                        w += size - r;
                    }
                    //如果集合A的大小放生改变
                    if (w != size) {
                        // 清除工作
                        for (int i = w; i < size; i++)
                            elementData[i] = null;
                        //记录集合中元素的改变(add/remove)
                        modCount += size - w;
                        //设置当前数组的大小
                        size = w;
                        //返回为true
                        modified = true;
                    }
                }
                return modified;
            }
    复制代码

    1、关于modCount变量的说明

    AbstractList包含一个modCount变量,它的初始值是0,当集合中的内容每被修改一次时(调用add(), remove()等方法),modCount加1

    2、关于返回值的说明

    如果集合A数组的大小没有改变,则返回false。如果集合A和集合B是完全相同的集合,也会返回false。

    复制代码
        public static void main(String[] args) {
            ArrayList<String> listA= new ArrayList<String>();
            listA.add("Tom");
            ArrayList<String> listB= new ArrayList<String>();
            listB.add("Tom");
            System.out.println(listA.retainAll(listB)); //false
        }
    复制代码

    即使两个集合没有交集,也会返回true。

    复制代码
    public static void main(String[] args) {
            ArrayList<String> listA= new ArrayList<String>();
            listA.add("Tom");
            ArrayList<String> listB= new ArrayList<String>();
            listB.add("Jack");
            System.out.println(listA.retainAll(listB));//true
        }
    复制代码

    所以,我们要记住:当集合A的大小改变的时候返回的是True,大小没有改变的时候返回的是False。

    三、正确的使用 retainAll 方法

    复制代码
    public static void main(String[] args) {
            ArrayList<String> listA= new ArrayList<String>();
            listA.add("Tom");
            ArrayList<String> listB= new ArrayList<String>();
            listB.add("Tom");
            listA.retainAll(listB);
            if(listA.size()>0){
                System.out.println("这两个集合有相同的交集");
            }else{
                System.out.println("这两个集合没有相同的交集");
            }
        }
    复制代码

    1、首先调用retainAll的方法

    2、通过判断集合的大小,来确定是否存在交集。不能通过方法返回的True和False来判断。

  • 相关阅读:
    电容
    51单片机
    三极管
    Scala 面向对象(八):特质(接口) 一
    Scala 面向对象(七):静态属性和静态方法
    Scala 面向对象(六):面向对象的特征二:继承 (一)
    Scala 面向对象(五):面向对象的特征一:封装性
    Scala 面向对象(四):import
    Scala 面向对象(三):package 包 (二)
    Scala 面向对象(二):package 包 (一) 入门
  • 原文地址:https://www.cnblogs.com/-1307/p/6477579.html
Copyright © 2020-2023  润新知