讀古今文學網 > 編寫高質量代碼:改善Java程序的151個建議 > 建議76:集合運算時使用更優雅的方式 >

建議76:集合運算時使用更優雅的方式

在初中代數中,我們經常會求兩個集合的並集、交集、差集等,在Java中也存在著此類運算,那如何實現呢?一提到此類集合操作,大部分的實現者都會說:對兩個集合進行遍歷,即可求出結果。是的,遍歷可以實現並集、交集、差集等運算,但這不是最優雅的處理方式。下面來看看如何進行更優雅、快速、方便的集合操作。

(1)並集

也叫做合集,把兩個集合加起來即可,這非常簡單,代碼如下:


public static void main(Stringargs){

List<String>list1=new ArrayList<String>();

list1.add("A");

list1.add("B");

List<String>list2=new ArrayList<String>();

list2.add("C");

list2.add("B");

//並集

list1.addAll(list2);

}


此時,list1中就是兩個列表的並集元素了。

(2)交集

計算兩個集合的共有元素,也就是你有我也有的元素集合,代碼如下:


list1.retainAll(list2);


其中的變量list1和list2是兩個列表,僅此一句話,list1中就只包含list1、list2中共有的元素了。注意retainAll方法會刪除list1中沒有出現在list2中的元素。

(3)差集

由所有屬於A但不屬於B的元素組成的集合,叫做A與B的差集,也就是我有你沒有的元素,代碼如下:


list1.removeAll(list2);


也很簡單,從list1中刪除出現在lis2的元素,即可得出list1與list2的差集部分。

(4)無重複的並集

什麼叫無重複的並集?並集是集合A加集合B,那如果集合A和集合B有交集(也就是並集的元素數量大於0),就需要確保並集的結果中只有一份交集,此為無重複的並集。此操作也比較簡單,代碼如下:


//刪除在list1中出現的元素

list2.removeAll(list1);

//把剩餘的list2元素加到list1中

list1.addAll(list2);


有讀者可能說了,求出兩個集合的並集,然後轉變成HashSet剔除重複元素不就解決問題了嗎?錯了,這樣解決是不行的,比如集合A有10個元素(其中有兩個元素值是相同的),集合B有8個元素,它們的交集有2個元素,我們可以計算出它們的並集是18個元素,而無重複的並集有16個元素,但是如果使用HashSet算法,算出來則只有15個元素,因為你把集合A中原本就重複的元素也剔除掉了。

讀者可能會很困惑,為什麼要介紹並集、交集、差集呢?那是因為只要去檢查一下代碼,就會發現,很少有程序員使用JDK提供的方法來實現這些集合操作,基本上都是採用的標準的嵌套for循環:要並集就是加法,要交集了就使用contains判斷是否存在,要差集了就使用!contains(不包含),有時候還要為這類操作提供一個單獨方法,看似很規範,但已經脫離了優雅的味道。

集合的這些操作在持久層中使用得非常頻繁,從數據庫中取出的就是多個數據集合,之後我們就可以使用集合的各種方法構建我們需要的數據了,需要兩個集合的and結果,那是交集,需要兩個集合的or結果,那是並集,需要兩個集合的not結果,那是差集。