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 }
上面就是示例代码。下面是我在写示例代码的时候,需要注意的一些事情。
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]
(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类中方法使用在第一次的代码中有写到。