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類中方法使用在第一次的代碼中有寫到。