CollectionUtils和Collections的使用


  CollectionUtils是對Collection集合操作的類方法,這個類不是java自帶的類方法,需要另外導入一個commons-collections.jar包才可以使用這個類中方法。因為這個CollectionUtils是對Collection集合操作的,所以我先簡單介紹一下Collection。

Collection(單例集合  ) 
├-List(有序,可重復 )  
│  ├-LinkedList(查詢速度慢,增刪快)   
│  ├-ArrayList(查詢速度快,增刪慢)  
│  └-Vector(線程安全的,操作效率低 )  
│     └-Stack   
└-Set(無序,不可重復) 
      ├-HashSet(使用了哈希表存取)
      │    └-LinkedHashSet
      └-SortedSet
               └-TreeSet(有序)
Map(鍵值對)  
├-Hashtable   
├-HashMap   
└-WeakHashMap     

注意:set是在HashMap的基礎上實現的,HashSet的存儲方式是把HashMap中的Key作為Set的對應存儲項。HashMap是非同步的,線程不安全的,Hashtable雖然是同步線程安全的,但是已經過期了。 現在使用ConcurrentHashMap,這個是線程安全同步的

 

這里有一篇關於collection詳細介紹的博客:http://skyuck.iteye.com/blog/526358

CollectionUtils類中的方法介紹

  1 package com.self.test1;
  2 
  3 import java.text.ParseException;
  4 import java.text.SimpleDateFormat;
  5 import java.util.ArrayList;
  6 import java.util.Arrays;
  7 import java.util.Collection;
  8 import java.util.Collections;
  9 import java.util.HashMap;
 10 import java.util.HashSet;
 11 import java.util.List;
 12 import java.util.Map;
 13 import java.util.Set;
 14 
 15 import org.apache.commons.collections4.CollectionUtils;
 16 import org.apache.commons.collections4.Transformer;
 17 
 18 //測試CollectionUtils中的使用方法
 19 public class CollectionUtilsTest {
 20 
 21     public static void main(String[] args) {
 22         List<String> alist = new ArrayList<String>();
 23         alist.add("ae");
 24         alist.add("ae");
 25         alist.add("b");
 26         alist.add("c");
 27         alist.add("c");
 28         alist.add("d");
 29         
 30         List<String> blist = new ArrayList<String>();
 31         blist.add("1");
 32         blist.add("2");
 33         blist.add("3");
 34         blist.add("ae");
 35         blist.add("ae");
 36         blist.add("ae");
 37         
 38         /*
 39          * 兩個集合的並集
 40          */
 41         
 42         /*
 43          * CollectionUtils.union:對兩個集合類型的數據進行並集,輸出的結果順序發生了改變,源碼中
 44          * 有這么一段代碼Set elts = new HashSet(a),它把傳過來的的集合數據存在在set類型的數據中,
 45          * HashSet的數據存取是沒有順序的,它是把數據解析成hashcode,根據hashcode進行存取的
 46          * 
 47          * 注意:如果兩個集合中有元素一樣的,合並之后只顯示其中某個集合中的元素,並不兩個集合中的相同元素都顯示。
 48          * 可以這么說,兩個個集合合並之后會顯示元素個數是兩個集合中的該元素的個數最多的。
 49          * 例如:兩個集合的元素都是一樣的,都是[1, 2, 3, ae],那么合並之后顯示結果為:[1, 2, 3, ae]
 50          * */
 51         System.out.println("============ CollectionUtils.union ================");
 52         Collection<String> unionList = CollectionUtils.union(alist, blist);
 53         System.out.println(unionList.toString());
 54         
 55         System.out.println("============ CollectionUtils.getCardinalityMap ================");
 56         /*
 57          * CollectionUtils.getCardinalityMap:返回給定的每個唯一元素的映射,以表示該元素在該元素中的出現次數。
 58         
 59             List<String> alist = new ArrayList<String>();
 60             alist.add("ae");
 61             alist.add("b");
 62             alist.add("c");
 63             alist.add("c");
 64             返回結果:
 65             {b=1, c=2, ae=1}
 66         */
 67         System.out.println(CollectionUtils.getCardinalityMap(alist).toString());
 68         System.out.println(CollectionUtils.getCardinalityMap(blist).toString());
 69         
 70         System.out.println("============ HashSet ================");
 71         Set elts = new HashSet(alist);
 72         System.out.println(elts);
 73         
 74         /*
 75          * 兩個集合的交集
 76          */
 77         Collection<String> intersectionList = CollectionUtils.intersection(alist, blist);
 78         System.out.println("============ CollectionUtils.intersection ==============");
 79         System.out.println(intersectionList.toString());
 80         
 81         /*
 82          * 兩個集合的補集
 83          *
 84          */
 85         Collection<String> disjunctionList = CollectionUtils.disjunction(alist, blist);
 86         System.out.println("============ CollectionUtils.disjunction ==============");
 87         System.out.println(disjunctionList.toString());
 88         
 89         /*
 90          * 兩個集合的相減 
 91          *
 92          */
 93         Collection<String> subtractList = CollectionUtils.subtract(alist, blist);
 94         System.out.println("============ CollectionUtils.subtract ==============");
 95         System.out.println(subtractList.toString());
 96         
 97         /*
 98          * 判斷兩個集合是否存在交集
 99          * return:如果兩個指定 collection 中有相同的元素,則返回 true。
100          */
101         boolean isContainsAny = CollectionUtils.containsAny(alist, blist);
102         System.out.println("============ CollectionUtils.containsAny ==============");
103         System.out.println("CollectionUtils.containsAny : " + isContainsAny);
104         
105         //return:如果兩個指定 collection 中有相同的元素,則返回 true。
106         boolean disjoint = Collections.disjoint(alist, blist);
107         System.out.println("Collections.disjoint : " + disjoint);
108         
109         /*
110          * 集合元素的個數,返回存取在Map中
111          *
112          */
113         Map getCardinalityMap = (HashMap) CollectionUtils.getCardinalityMap(alist);
114         System.out.println("============ CollectionUtils.getCardinalityMap ==============");
115         System.out.println(getCardinalityMap.toString());
116         
117         /*
118          * 判斷第一個集合是第二個集合的子集(子集是包括本身的元素的集合,也就是說自己也可以包含自己)
119          
120              List<String> alist = new ArrayList<String>();
121             alist.add("ae");
122             alist.add("ae");
123             
124             List<String> blist = new ArrayList<String>();
125             blist.add("ae");
126             blist.add("ae");
127             
128             結果:
129             ============ CollectionUtils.isSubCollection ==============
130             true
131          *
132          */
133         boolean isSubCollection = CollectionUtils.isSubCollection(blist,alist);
134         System.out.println("============ CollectionUtils.isSubCollection ==============");
135         System.out.println(isSubCollection);
136         
137         
138         /*
139          * 判斷第一個集合是第二個集合的真子集(真子集是除本身的元素的集合)
140          
141              List<String> alist = new ArrayList<String>();
142             alist.add("ae");
143             alist.add("ae");
144             
145             List<String> blist = new ArrayList<String>();
146             blist.add("ae");
147             blist.add("ae");
148             
149             結果:
150             ============ CollectionUtils.isProperSubCollection ==============
151             false
152          *
153          */
154         boolean isProperSubCollection = CollectionUtils.isProperSubCollection(blist,alist);
155         System.out.println("============ CollectionUtils.isProperSubCollection ==============");
156         System.out.println(isProperSubCollection);
157         
158         /*
159          * 判斷兩個集合是否相等
160          *
161          */
162         boolean isEqualCollection = CollectionUtils.isEqualCollection(alist, blist);
163         System.out.println("============ CollectionUtils.isEqualCollection ==============");
164         System.out.println(isEqualCollection);
165         
166         /*
167          * 判斷元素在某個集合中的個數
168          
169          源碼:
170          public static int cardinality(Object obj, final Collection coll) {
171             if (coll instanceof Set) {
172                 return (coll.contains(obj) ? 1 : 0);
173             }
174             if (coll instanceof Bag) {
175                 return ((Bag) coll).getCount(obj);
176             }
177             int count = 0;
178             if (obj == null) {
179                 for (Iterator it = coll.iterator();it.hasNext();) {
180                     if (it.next() == null) {
181                         count++;
182                     }
183                 }
184             } else {
185                 for (Iterator it = coll.iterator();it.hasNext();) {
186                     if (obj.equals(it.next())) {
187                         count++;
188                     }
189                 }
190             }
191             return count;
192         }
193          
194          源碼處理的思想挺好的,所以我才把這段源碼粘貼出來,先對Collection類型進行判斷處理,然后對傳過來的參數進行判斷處理
195          *
196          */
197         @SuppressWarnings("deprecation")
198         int cardinality = CollectionUtils.cardinality("ae", blist);
199         System.out.println("============ CollectionUtils.cardinality ==============");
200         System.out.println(cardinality);
201         
202         /*
203          * 集合元素中第一個符合查詢條件的元素
204          *
205          */
206         @SuppressWarnings("deprecation")
207         String find = CollectionUtils.find(alist,ele -> !ele.equals("ae"));
208         System.out.println("============ CollectionUtils.find ==============");
209         System.out.println(find);
210         
211         /*
212          * 集合元素的過濾
213          *
214          */
215         boolean filter = CollectionUtils.filter(alist,ele -> ele.equals("ae"));
216         System.out.println("============ CollectionUtils.filter ==============");
217         System.out.println(alist.toString());
218         
219         /*
220          * 集合元素按照給定的格式Transformer進行轉化
221          *
222          */
223         System.out.println("============ CollectionUtils.transform ==============");
224         List<String> clist = new ArrayList<String>();
225         clist.add("20170927101124");
226         CollectionUtils.transform(clist,new Transformer(){
227             SimpleDateFormat fmt =new SimpleDateFormat("yyyyMMddhhmmss");
228             @Override
229             public String transform(Object arg0) {
230                 try {
231                     return fmt.parse((String)arg0).toString();
232                 } catch (ParseException e) {
233                     e.printStackTrace();
234                 }
235                 return null;
236             }});
237         System.out.println(clist);
238         
239         
240         /*
241          * 集合中符合查詢條件的元素的個數
242          *
243          */
244         int countMatches = CollectionUtils.countMatches(alist,ele -> ele.equals("ae"));
245         System.out.println("============ CollectionUtils.countMatches ==============");
246         System.out.println("CollectionUtils.countMatches : " + countMatches);
247         
248         //返回指定 collection 中等於指定對象的元素數。與上面的不同之處在於第二個參數,只能是object
249         int frequency = Collections.frequency(alist,"ae");
250         System.out.println("Collections.frequency : " + frequency);
251         
252         /*
253          * 判斷集合中是否符合有查詢條件的元素
254          *
255          */
256         boolean exists = CollectionUtils.exists(alist,ele -> ele.equals("ae"));
257         System.out.println("============ CollectionUtils.exists ==============");
258         System.out.println(exists);
259         
260         /*
261          * 篩選出集合中所有的元素符合查詢的條件
262          *
263          */
264         List<String> select = (List<String>) CollectionUtils.select(alist,ele -> ele.equals("ae"));
265         System.out.println("============ CollectionUtils.select ==============");
266         System.out.println(select.toString());
267         
268         /*
269          * 篩選出集合中所有的元素不符合查詢的條件
270          *
271          */
272         List<String> dlist = new ArrayList<String>();
273         dlist.add("ae");
274         dlist.add("ae");
275         dlist.add("b");
276         dlist.add("c");
277         dlist.add("c");
278         dlist.add("d");
279         List<String> selectRejected = (List<String>) CollectionUtils.selectRejected(dlist,ele -> ele.equals("b"));
280         System.out.println("============ CollectionUtils.selectRejected ==============");
281         System.out.println(selectRejected.toString());
282         
283         /*
284          * 集合元素添加,如果添加元素是null,就返回false,不添加,否則添加新元素
285          *
286          */
287         boolean addIgnoreNull =  CollectionUtils.addIgnoreNull(dlist,"db");
288         System.out.println("============ CollectionUtils.addIgnoreNull ==============");
289         System.out.println(dlist.toString());
290         
291         /*
292          * 將所有指定元素添加到指定 collection 中,
293          * 第二個參數中的元素添加到第一個參數集合中尾部
294          *
295          */
296         boolean addAll =  CollectionUtils.addAll(dlist,blist);
297         System.out.println("============ CollectionUtils.addAll ==============");
298         System.out.println("CollectionUtils.addAll : " + dlist.toString());
299         
300         
301          //用Collections.addAll只能添加元素,不能使用集合,但是可以使用多個元素
302          boolean saddAll =  Collections.addAll(dlist,"aaaa");
303          System.out.println("Collections.addAll : " + dlist.toString());
304         
305         
306         /*
307          * 集合中得到指定下標的元素
308          *
309          */
310         String get =  (String)CollectionUtils.get(alist,1);
311         System.out.println("============ CollectionUtils.get ==============");
312         System.out.println(get);
313         
314         /*
315          * 集合的大小
316          *
317          */
318         int size =  CollectionUtils.size(alist);
319         System.out.println("============ CollectionUtils.size ==============");
320         System.out.println(size);
321         
322         /*
323          * 判斷集合是否為空
324          *
325          */
326         List<String> elist = new ArrayList<String>();
327         /*elist.add("");
328         elist.add("ae");
329         elist.add("b");
330         elist.add("c");
331         elist.add("c");
332         elist.add("d");*/
333         boolean sizeIsEmpty =  CollectionUtils.sizeIsEmpty(elist);
334         System.out.println("============ CollectionUtils.sizeIsEmpty ==============");
335         System.out.println(sizeIsEmpty);
336         
337         /*
338          * 判斷集合是否為空
339          *
340          */
341         boolean isEmpty =  CollectionUtils.isEmpty(elist);
342         System.out.println("============ CollectionUtils.isEmpty ==============");
343         System.out.println(isEmpty);
344         
345         /*
346          * 判斷集合是否為不為空
347          *
348          */
349         boolean isNotEmpty =  CollectionUtils.isNotEmpty(elist);
350         System.out.println("============ CollectionUtils.isNotEmpty ==============");
351         System.out.println(isNotEmpty);
352         
353         /*
354          * array中的元素從后往前顯示
355          *
356          */
357         Object[] array = new Object[]{1,2,3,4,5,5,0,6};
358         CollectionUtils.reverseArray(array);
359         System.out.println("============ CollectionUtils.reverseArray ==============");
360         System.out.println("CollectionUtils.reverseArray : " + Arrays.asList(array));
361         /*for(Object obj : array){
362             System.out.print(obj + "  ");
363         }*/
364         
365         //反轉可以使用:Collections.reverse
366         Collections.reverse(blist);
367         System.out.println("Collections.reverse : " +blist);
368         
369         
370         /*
371          * 如果這個集合BoundedCollection接口,那么返回繼承接口中的最大數字,如果沒有繼承,則返回-1
372          */
373         /*int maxSize = CollectionUtils.maxSize(alist);
374         System.out.println("============ CollectionUtils.maxSize ==============");
375         System.out.println(maxSize);*/
376         
377         /*
378          * 第一個集合中的每個元素與第二個集合中的元素進行匹配,
379          * 匹配成功就添加到要返回的集合中。返回第一個集合中的元素和第二個集合中元素進行匹配相等的
380          * 也就是說返回集合中的元素個數多少個和第一個集合元素個數有關
381          
382              例如:
383              List<String> flist = new ArrayList<String>();
384             flist.add("ae");
385             
386             List<String> hlist = new ArrayList<String>();
387             hlist.add("1");
388             hlist.add("ae");
389             hlist.add("ae");
390             
391             結果:
392             ============ CollectionUtils.retainAll ==============
393             [ae]
394 
395          *
396          */
397         List<String> flist = new ArrayList<String>();
398         flist.add("ae");
399         /*flist.add("ae");
400         flist.add("ae");
401         flist.add("ae");
402         flist.add("b");
403         flist.add("c");
404         flist.add("c");
405         alist.add("d");*/
406         
407         List<String> hlist = new ArrayList<String>();
408         hlist.add("1");
409         /*hlist.add("2");
410         hlist.add("3");
411         hlist.add("ae");*/
412         hlist.add("ae");
413         hlist.add("ae");
414         List<String> retainAll = (List<String>) CollectionUtils.retainAll(flist,hlist);
415         System.out.println("============ CollectionUtils.retainAll ==============");
416         System.out.println(retainAll);
417         
418         
419         /*
420          * 
421              public static Collection union(final Collection a, final Collection b) {
422                 ArrayList list = new ArrayList();
423                 Map mapa = getCardinalityMap(a);
424                 Map mapb = getCardinalityMap(b);
425                 Set elts = new HashSet(a);
426                 elts.addAll(b);
427                 Iterator it = elts.iterator();
428                 while(it.hasNext()) {
429                     Object obj = it.next();
430                     for(int i=0,m=Math.max(getFreq(obj,mapa),getFreq(obj,mapb));i<m;i++) {
431                         list.add(obj);
432                     }
433                 }
434                 return list;
435             }
436             
437             1.兩個集合求並集,是把兩個個集合合並之后會顯示元素個數是兩個集合中的該元素的個數最多的。
438                 也就會出現兩個集合中元素一樣的情況下,只顯示其中某個集合中該元素個數最多的那個集合中的
439             2.兩個集合求交集,與求並集的不同之處就是for中的條件不同(for(int i=0,m=Math.min(getFreq(obj,mapa),getFreq(obj,mapb));i<m;i++)),
440                 如果兩個集合中各自有相同元素的個數大於1,那么交集輸出該元素的個數是該元素在兩個集合中最少個數的元素。
441                     List<String> alist = new ArrayList<String>();
442                     alist.add("ae");
443                     alist.add("ae");
444                     alist.add("b");
445                     alist.add("c");
446                     alist.add("c");
447                     alist.add("d");
448                     
449                     List<String> blist = new ArrayList<String>();
450                     blist.add("1");
451                     blist.add("2");
452                     blist.add("3");
453                     blist.add("ae");
454                     blist.add("ae");
455                     blist.add("ae");
456                     
457                     結果:[ae, ae]
458                     
459             3.兩個集合求補集,與求並集的不同之處就是for中的條件不同( for(int i=0,m=((Math.max(getFreq(obj,mapa),getFreq(obj,mapb)))-(Math.min(getFreq(obj,mapa),getFreq(obj,mapb))));i<m;i++))
460             4.兩個集合相減,返回第一個集合里面的不存在第二個集合中的元素
461             
462          */
463         
464         
465         
466     }
467     
468 
469 }
View Code

上面就是示例代碼。下面是我在寫示例代碼的時候,需要注意的一些事情。

1.CollectionUtils.union:對兩個集合類型的數據進行並集,輸出的結果順序發生了改變,源碼中有這么一段代碼Set elts = new HashSet(a),它把傳過來的的集合數據存在在set類型的數據中,HashSet的數據存取是沒有順序的,它是把數據解析成hashcode,根據hashcode進行存取的。

注意:如果兩個集合中有元素一樣的,合並之后只顯示其中某個集合中的元素,並不兩個集合中的相同元素都顯示。可以這么說,兩個個集合合並之后會顯示元素個數是兩個集合中的該元素的個數最多的。例如:兩個集合的元素都是一樣的,都是[1, 2, 3, ae],那么合並之后顯示結果為:[1, 2, 3, ae]。

2.CollectionUtils.cardinality是判斷元素在某個集合中的個數。源碼處理的思想挺好的,所以我才把這段源碼粘貼出來,先對Collection類型進行判斷處理,然后對傳過來的參數進行判斷處理。

public static int cardinality(Object obj, final Collection coll) {
            if (coll instanceof Set) {
                return (coll.contains(obj) ? 1 : 0);
            }
            if (coll instanceof Bag) {
                return ((Bag) coll).getCount(obj);
            }
            int count = 0;
            if (obj == null) {
                for (Iterator it = coll.iterator();it.hasNext();) {
                    if (it.next() == null) {
                        count++;
                    }
                }
            } else {
                for (Iterator it = coll.iterator();it.hasNext();) {
                    if (obj.equals(it.next())) {
                        count++;
                    }
                }
            }
            return count;
        }

3.CollectionUtils.retainAll:第一個集合中的每個元素與第二個集合中的元素進行匹配, 匹配成功就添加到要返回的集合中。返回第一個集合中的元素和第二個集合中元素進行匹配相等的,也就是說返回集合中的元素個數多少個和第一個集合元素個數有關。

             List<String> flist = new ArrayList<String>();
            flist.add("ae");
            
            List<String> hlist = new ArrayList<String>();
            hlist.add("1");
            hlist.add("ae");
            hlist.add("ae");
            
            結果:
            ============ CollectionUtils.retainAll ==============
            [ae]

4.CollectionUtils.subtract:是兩個集合的相減 ,返回第一個集合里面的不存在第二個集合中的元素。

5.關於兩個集合的交集、並集、補集的源碼分析,這三個方法的源碼運用非常巧妙的算法,所以跟大家分享一下。

下面是兩個集合的並集源碼:

 public static Collection union(final Collection a, final Collection b) {
                ArrayList list = new ArrayList();
                Map mapa = getCardinalityMap(a);
                Map mapb = getCardinalityMap(b);
                Set elts = new HashSet(a);
                elts.addAll(b);
                Iterator it = elts.iterator();
                while(it.hasNext()) {
                    Object obj = it.next();
                    for(int i=0,m=Math.max(getFreq(obj,mapa),getFreq(obj,mapb));i<m;i++) {
                        list.add(obj);
                    }
                }
                return list;
            }

(1)兩個集合求並集,是把兩個個集合合並之后會顯示元素個數是兩個集合中的該元素的個數最多的。也就會出現兩個集合中元素一樣的情況下,只顯示其中某個集合中該元素個數最多的那個集合中的
(2)兩個集合求交集,與求並集的不同之處就是for中的條件不同(for(int i=0,m=Math.min(getFreq(obj,mapa),getFreq(obj,mapb));i<m;i++)),如果兩個集合中各自有相同元素的個數大於1,那么交集輸出該元素的個數是該元素在兩個集合中最少個數的元素。

List<String> alist = new ArrayList<String>();
alist.add("ae");
alist.add("ae");
alist.add("b");
alist.add("c");
alist.add("c");
alist.add("d");

List<String> blist = new ArrayList<String>();
blist.add("1");
blist.add("2");
blist.add("3");
blist.add("ae");
blist.add("ae");
blist.add("ae");

結果:[ae, ae]
View Code

(3)兩個集合求補集,與求並集的不同之處就是for中的條件不同( for(int i=0,m=((Math.max(getFreq(obj,mapa),getFreq(obj,mapb)))-(Math.min(getFreq(obj,mapa),getFreq(obj,mapb))));i<m;i++))

Collections類中方法使用在第一次的代碼中有寫到。

 


免責聲明!

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



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