一、 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來判斷。