zoukankan      html  css  js  c++  java
  • 瞬间教你学会使用java中list的retainAll方法

    retainAll方法简介

    当我们有两个list集合的时候,我们可以使用retainAll方法求得两个list集合的子集。retainAll是Collection接口中提供的一个方法,各个实现类有自己的实现方式,我们这里介绍ArrayList的实现方式。

    retainAll源码深入

    可以看到collection接口中的retainAll方法,需要传入一个集合。

    boolean retainAll(Collection<?> c);
    

    进入arrayList的方法实现。可以看到如下代码:

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

    由以上代码可知,传入的集合不能为null。接下来看看batchRemove方法。

        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;
        }
    

    我们看到上述方法的流程如下:
    首先获得当前对象的所有元素,然后通过r和w变量标记两个集合公共元素的个数。初始化标志位为false。然后进入循环遍历当前集合,如果传入的集合中包含当前集合的元素,就直接将这个元素保存下来。最后到finally块中,如果r不等于size,证明在循环的过程中出现了异常,然后将剩余的元素进行复制,重新计算数组的剩余元素值。如果剩余的元素值不等于size,则将多余的位置进行清空。更改modcount的值。这个modcount是父类abstarctlist的值,初始值为0,集合中的内容没修改一次则增加1。最后重新设置size的大小。返回是否修改值。

    retainAll返回值的说明

    这里有两个说明。
    第一个:如果集合A数组的大小没有改变,则返回false。如果集合A和集合B是完全相同的集合,也会返回false。

    public static void main(String[] args) {
            ArrayList<String> list1= new ArrayList<String>();
            list1.add("123");
            ArrayList<String> list2= new ArrayList<String>();
            list2.add("123");
            System.out.println(list1.retainAll(list2)); 
        }
    

    如上代码会返回false。
    第二个:两个集合没有交集,会返回true。

    public static void main(String[] args) {
            ArrayList<String> list1= new ArrayList<String>();
            list1.add("123");
            ArrayList<String> list2= new ArrayList<String>();
            list2.add("12345");
            System.out.println(list1.retainAll(list2));
        }
    

    如上代码会返回true。
    总结:当集合A的大小改变的时候返回的是True,大小没有改变的时候返回的是False。

    retainAll的判断方法

    public static void main(String[] args) {
            ArrayList<String> list1= new ArrayList<String>();
            list1.add("123");
            ArrayList<String> list2= new ArrayList<String>();
            list2.add("123");
            list1.retainAll(list2);
            if(list1.size()>0){
                System.out.println("有交集");
            }else{
                System.out.println("没有交集");
            }
        }
    

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

    retainAll的实际效果使用

    我们声明两个集合,通过调用retainAll,保留两个集合的交集。最后再看输出的效果。

        public static void main(String[] args) {
            Collection collection1 = new ArrayList();
            collection1.add("a");
            collection1.add("b");
            collection1.add("c");
            Collection collection2 = new ArrayList();
            collection2.add("ab");
            collection2.add("abc");
            collection2.add('a');
            System.out.println(collection1);
            boolean flag = collection1.retainAll(collection2);
            System.out.println(flag);
            System.out.println(collection1);
        }
    
    

    执行结果如下:

    [a, b, c]
    true
    [a]
    

    保留了两个结合的交集。

    总结

    list的retainAll方法的介绍和分析到此结束,文中难免有不足之处,望大家指正交流。

  • 相关阅读:
    Java实现蓝桥杯正则切分
    VS2013 预定义的宏
    VS2015编译boost1.62
    linux 下Qt WebEngine 程序打包简单记录
    Visual Studio 默认保存为UTF8编码
    微型Http服务器Tiny Http Server
    Bootstrap Paginator分页插件
    Web前端框架与类库
    开发与常用工具清单
    程序员修炼之道
  • 原文地址:https://www.cnblogs.com/jichi/p/12892150.html
Copyright © 2011-2022 走看看