一、Collections 概述
二、常用方法
public static <T> boolean addAll(Collection<? super T> c,T... elements)將所有指定元素添加到指定 collection 中。 public static <T> int binarySearch(List<? extends Comparable<? super T>> list,T key)在List集合中查找某個元素的下標,但是List的元素必須是T或T的子類對象,而且必須是可比較大小的,即支持自然排序的。而且集合也事先必須是有序的,否則結果不確定。 public static <T> int binarySearch(List<? extends T> list,T key,Comparator<? super T> c)在List集合中查找某個元素的下標,但是List的元素必須是T或T的子類對象,而且集合也事先必須是按照c比較器規則進行排序過的,否則結果不確定。 public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll)在coll集合中找出最大的元素,集合中的對象必須是T或T的子類對象,而且支持自然排序 public static <T> T max(Collection<? extends T> coll,Comparator<? super T> comp)在coll集合中找出最大的元素,集合中的對象必須是T或T的子類對象,按照比較器comp找出最大者 public static void reverse(List<?> list)反轉指定列表List中元素的順序。 public static void shuffle(List<?> list) List 集合元素進行隨機排序,類似洗牌 public static <T extends Comparable<? super T>> void sort(List<T> list)根據元素的自然順序對指定 List 集合元素按升序排序 public static <T> void sort(List<T> list,Comparator<? super T> c)根據指定的 Comparator 產生的順序對 List 集合元素進行排序 public static void swap(List<?> list,int i,int j)將指定 list 集合中的 i 處元素和 j 處元素進行交換 public static int frequency(Collection<?> c,Object o)返回指定集合中指定元素的出現次數 public static <T> void copy(List<? super T> dest,List<? extends T> src)將src中的內容復制到dest中 public static <T> boolean replaceAll(List<T> list,T oldVal,T newVal):使用新值替換 List 對象的所有舊值
public static <T> List<T> synchronizedList(List<T> list):返回指定列表支持的同步(線程安全的)列表
public static <T> List<T> unmodifiableList(List<? extends T> list)返回指定列表的不可修改視圖
注意:
Collections 類中提供了多個 synchronizedXXX() 方法,該方法可使指定集合包裝成線程同步的集合,從而可以解決多線程並發訪問集合時的線程安全問題。
Collections 類中提供了多個 unmodifiableXXX() 方法,該方法返回指定 XXX 的不可修改的視圖。
說明:
public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) 方法的泛型形參為什么要設定上限為 Object & Comparable?
這是為了當泛型擦除時,按照 Object 處理,而不是 Comparable 處理,這樣就可以和 JDK1.5 之前沒有泛型的API 保持一致。
Demo:
1 ArrayList<String> list = new ArrayList<>(); 2 Collections.addAll(list,"a","b","c","d","e"); // 往集合中添加一些元素。
3 System.out.println(list);//[a, b, c, d, e]
4 Collections.shuffle(list); // 打亂集合順序
5 System.out.println(list);//[b, d, c, a, e], [b, d, c, a, e]
三、sort 方法
public static <T> void sort(List<T> list) 方法
該方法將集合中元素按照默認規則排序,默認是升序。
注意:被排序的集合里邊存儲的元素,必須實現Comparable,重寫接口中的方法compareTo定義排序的規則。
四、Comparator 比較器
上面使用了 sort() 方法進行的是默認排序,如果想要指定順序那該怎么辦呢?
public static <T> void sort(List<T> list,Comparator<? super T> ):將集合中元素按照指定規則排序。
首先,先來研究下面的這個方法
public static <T> void sort(List<T> list):將集合中元素按照默認規則排序。
Demo:
1 public class CollectionsDemo2 { 2 public static void main(String[] args) { 3 ArrayList<String> list = new ArrayList<String>(); 4 list.add("cba"); 5 list.add("aba"); 6 list.add("sba"); 7 list.add("nba"); 8 //排序方法
9 Collections.sort(list); 10 System.out.println(list); 11 } 12 } 13 結果:[aba, cba, nba, sba]
通過上面的Demo可以看出使用的默認規則完成字符串的排序,那么默認規則是如何定義出來的呢?
上面我們存放的是一個 String 類,打開String類型如下:
public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
我們發現 String 類實現了這個接口,並完成了比較規則的定義,但是這樣就把規則寫死了,如果想按照第一個字符降序排列,這就需要修改 String 的源代碼,但是這是不可能的,這時我們就可以使用 comparator 接口來實現。
public static <T> void sort(List<T> list,Comparator<? super T> )
Comparator 這個接口,位於 java.util 包下面,排序是 comparator 能實現的功能之一,該接口代表一個比較器,比較器具有可比性。
下面看一下這個比較的方法:
1 public int compare(String o1, String o2)`:比較其兩個參數的順序。 2
3 兩個對象比較的結果有三種:大於,等於,小於。 4
5 如果要按照升序排序, 6 則o1 小於o2,返回(負數),相等返回0,01大於02返回(正數) 7 如果要按照降序排序 8 則o1 小於o2,返回(正數),相等返回0,01大於02返回(負數)
Demo:按第一個單詞降序
1 public class CollectionsDemo3 { 2 public static void main(String[] args) { 3 ArrayList<String> list = new ArrayList<String>(); 4 list.add("cba"); 5 list.add("aba"); 6 list.add("sba"); 7 list.add("nba"); 8 //排序方法 按照第一個單詞的降序
9 Collections.sort(list, new Comparator<String>() { 10 @Override 11 public int compare(String o1, String o2) { 12 return o2.charAt(0) - o1.charAt(0); 13 } 14 }); 15 System.out.println(list); 16 } 17 } 18 結果:[sba, nba, cba, aba]
五、Comparable 和 Comparator 兩個接口的區別
Comparable:
強行對實現它的每個類的對象進行整體排序。這種排序被稱為類的自然排序,類的 compaetTo 方法被稱為她的自然比較方法。
只能在類中實現 compareTo() 一次,不能經常修改類的代碼實現自己想要的排序,實現此接口的對象列表(和數組)可以通過 Collection.sort (和 Arrays.sort)進行自動排序,對象可以用作有序映射中的鍵或有序集合中的元素,無序指定比較器。
comparator:
強行對某個對象進行整體排序。可以將 Comparator 傳遞給 sort 方法(如Collection.sort 或 Array.sort),從而允許在排序上實現精確控制。
還可以使用 Comparator 來控制某些數據結構(如有序 set 或有序的映射)的順序,或者為那些沒有自然順序的對象 collection 提供排序。
Demo:

1 // 自定義 Student 類 2 public class Student{ 3 private String name; 4 private int age; 5 6 public Student() { 7 } 8 9 public Student(String name, int age) { 10 this.name = name; 11 this.age = age; 12 } 13 14 public String getName() { 15 return name; 16 } 17 18 public void setName(String name) { 19 this.name = name; 20 } 21 22 public int getAge() { 23 return age; 24 } 25 26 public void setAge(int age) { 27 this.age = age; 28 } 29 30 @Override 31 public String toString() { 32 return "Student{" + 33 "name='" + name + '\'' + 34 ", age=" + age + 35 '}'; 36 } 37 }
測試類:

1 public class Demo { 2 3 public static void main(String[] args) { 4 // 創建四個學生對象 存儲到集合中 5 ArrayList<Student> list = new ArrayList<Student>(); 6 7 list.add(new Student("rose",18)); 8 list.add(new Student("jack",16)); 9 list.add(new Student("abc",16)); 10 list.add(new Student("ace",17)); 11 list.add(new Student("mark",16)); 12 13 14 /* 15 讓學生 按照年齡排序 升序 16 */ 17 // Collections.sort(list);//要求 該list中元素類型 必須實現比較器Comparable接口 18 19 20 for (Student student : list) { 21 System.out.println(student); 22 } 23 24 25 } 26 }
這個時候發現調用 Collections.sort()方法的時候 程序報錯了。
原因:如果想要集合中的元素完成排序,那么必須要實現比較器Comparable接口。
public class Student implements Comparable<Student>{
....
@Override
public int compareTo(Student o) {
return this.age-o.age;//升序
}
}
再補充上面的代碼后,就 OK了。
當然了,如果在使用的時候,想要獨立的定義規則去使用 可以采用Collections.sort(List list,Comparetor<T> c)方式,自己定義規則如下:
Collections.sort(list, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o2.getAge()-o1.getAge();//以學生的年齡降序
}
});
擴展:如果年齡相同,按姓名第一個字母排序
Collections.sort(list, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
// 年齡降序
int result = o2.getAge()-o1.getAge();//年齡降序
if(result==0){//第一個規則判斷完了 下一個規則 姓名的首字母 升序
result = o1.getName().charAt(0)-o2.getName().charAt(0);
}
return result;
}
});
總結:
對於自定義的類型來說,如果想要調用 Collections.sort() 或 Arrays.sort() 方法時,必須指定一個比較器。
1、在當前類中 實現 Comparable 接口,重寫其中的 compareTo() 方法,在方法里面指定比較方式。
2、在調用 sort() 方法的時候,在第二個參數的位置,new Comparor 對象,然后重寫 compare 方法。