1. 程式人生 > >瞬間教你學會使用java中list的retainAll方法

瞬間教你學會使用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 list1= new ArrayList(); list1.add("123"); ArrayList list2= new ArrayList(); list2.add("123"); System.out.println(list1.retainAll(list2)); } ``` 如上程式碼會返回false。 第二個:兩個集合沒有交集,會返回true。 ``` public static void main(String[] args) { ArrayList list1= new ArrayList(); list1.add("123"); ArrayList list2= new ArrayList(); list2.add("12345"); System.out.println(list1.retainAll(list2)); } ``` 如上程式碼會返回true。 總結:當集合A的大小改變的時候返回的是True,大小沒有改變的時候返回的是False。 ### retainAll的判斷方法 ``` public static void main(String[] args) { ArrayList list1= new ArrayList(); list1.add("123"); ArrayList list2= new ArrayList(); 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方法的介紹和分析到此結束,文中難免有不足之處,望大家指正