Java - Implement collection intersection

最近在處理的資料需要面對intersection的部分,在這邊要探討的是程式上的處理,主要有在

下土法煉鋼的第一版本及collection Set內使用retainAll的版本!

假設我們有八筆資料如下:

  1. 'C0014852', 'C0266015', 'ABC'
  2. 'C0014852', 'C0021070', 'ABC'
  3. 'C0014852', 'C0024299', 'ABC'
  4. 'C0014852', 'C0024211', 'ABC'
  5. 'C0014852', 'C0266015', 'DEF'
  6. 'C0014852', 'C0021070', 'DEF'
  7. 'C0014852', 'C0024299', 'DEF'
  8. 'C0014852', 'C0033122', 'DEF'

首先我們兩種型態下的各四筆資料,以type前的兩個ID算一個pair,若八筆資料中有不同型態

的兩個pair是一樣的,就算是有交集的情況!如:

  1. 'C0014852', 'C0266015', 'ABC'
  2. 'C0014852', 'C0266015', 'DEF'

作法一:

宣告一個變數:

  1. Map<String, Integer> pair2num = new HashMap<String, Integer>();

利用此Map的key當pair,value的部分計算此pair出現幾次,計數的判斷如下:
  1. ...
  2. if(!pair2num.containsKey(pairs)){
  3. pairsnum = 1;
  4. }else{
  5. pairsnum = pair2num.get(pairs)+1;
  6. }
  7. pair2num.put(pairs, pairsnum);
  8. ...
  9. for(Integer d : pair2num.values()){
  10. if(d == moreType){
  11. intersect_num++;
  12. }
  13. }

最後針對pair2num的value做判斷,假設我今天要做兩個type的交集,那麼moreType即等於2,

在這邊要注意的是這些例子是以ID1, ID2, Type為唯一的,因此'C0014852', 'C0266015', 'ABC'

不會出現相同的兩次為條件。在上面的intersect_num就可以計算有幾組交集的組數!

作法二:

一樣針對上面的資料,宣告一變數如下:
  1. Map<String, Set<String>> type2pair = new HashMap<String, Set<String>>();
這個變數要儲存的是,key為type (如:ABC or DEF),value為pair。
  1. Set<String> pairs = null;
  2. if(!type2pair.containsKey(type)){
  3. pairs = new HashSet<String>();
  4. }else{
  5. pairs = type2pair.get(type);
  6. }
  7. pairs.add(pair);
  8. type2pair.put(type, pairs);
  9. ....
  10. for(Set<String> setElement : type2pairs.values()){
  11. if(tempSet == null){
  12. tempSet = setElement;
  13. }else{
  14. tempSet.retainAll(setElement);
  15. }
  16. }
首先檢查type2pair的key是否存在,在建立此value的Set,建立完畢後。再透過迴圈,將第一

個Set儲存至tempSet內,第二個Set與第一個Set,使用retainAll method,即可以針對第一個

Set內與第二個Set相同的資料保留,不一樣的資料即會被remove,因此tempSet.size()即等於

交集的個數。切記,如果使用retainAll被排除的資料會remove,這也表示type2pairs的第一個

Set也會受影響,因為按照語法tempSet = setElement;(assign reference),type2pairs如果還要

再利用就要特別注意!

一開始是先利用作法一,後來想說看看retainAll是做啥的,結果取代後整個就比較單純!

留言