瞬間教你學會使用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方法的介紹和分析到此結束,文中難免有不足之處,望大家指正交流。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM