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