/** * @author hjn * @entity Student * @date 2017年5月23日15:22:18 */ public class Student { private String stuName; private String stuSex; private Integer stuAge; public Student() { } public Student(String stuName, String stuSex, Integer stuAge) { super(); this.stuName = stuName; this.stuSex = stuSex; this.stuAge = stuAge; } public String getStuName() { return stuName; } public void setStuName(String stuName) { this.stuName = stuName; } public String getStuSex() { return stuSex; } public void setStuSex(String stuSex) { this.stuSex = stuSex; } public Integer getStuAge() { return stuAge; } public void setStuAge(Integer stuAge) { this.stuAge = stuAge; } @Override public String toString() { return "學生 [姓名=" + stuName + ", 性別=" + stuSex + ", 年齡=" + stuAge + "]"; } }
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; /** * @author hjn * @class TestList * @date 2017年5月23日15:24:18 */ public class TestList { public static void main(String[] args) { Student stu1=new Student("張三","男",25); Student stu2=new Student("李四","男",22); Student stu3=new Student("王五","男",26); Student stu4=new Student("趙六","男",25); Student stu5=new Student("麻七","男",28); Student stu6=new Student("二狗","男",21); List<Student> list=new ArrayList<Student>(); list.add(stu1);list.add(stu2); list.add(stu3);list.add(stu4); list.add(stu5);list.add(stu6); System.out.println("排序前:"); for (Student student : list) { System.out.println(student.toString()); } Collections.sort(list, new Comparator<Student>(){ @Override public int compare(Student o1, Student o2) { if(o1.getStuAge()>o2.getStuAge()){ return 1; } if(o1.getStuAge()==o2.getStuAge()){ return 0; } return -1; } }); System.out.println("排序后:"); for (Student student : list) { System.out.println(student.toString()); } } }
輸出結果:
排序前: 學生 [姓名=張三, 性別=男, 年齡=25] 學生 [姓名=李四, 性別=男, 年齡=22] 學生 [姓名=王五, 性別=男, 年齡=26] 學生 [姓名=趙六, 性別=男, 年齡=25] 學生 [姓名=麻七, 性別=男, 年齡=28] 學生 [姓名=二狗, 性別=男, 年齡=21] 排序后: 學生 [姓名=二狗, 性別=男, 年齡=21] 學生 [姓名=李四, 性別=男, 年齡=22] 學生 [姓名=張三, 性別=男, 年齡=25] 學生 [姓名=趙六, 性別=男, 年齡=25] 學生 [姓名=王五, 性別=男, 年齡=26] 學生 [姓名=麻七, 性別=男, 年齡=28]
Collections的sort方法:
public static <T extends Comparable<? supper T>> void sort(List<T> list)
根據元素的自然順序 對指定列表按升序進行排序。列表中的所有元素都必須實現 Comparable接口。此外,列表中的所有元素都必須是可相互比較的。也就是說對於列表中的任何e1和e2元素,e1.compareTo(e2)不得拋出ClassCastException。
此排序方法具有穩定性,不會因為調用sort方法而對相等的元素進行重新排序。
指定列表必須是可修改的,但不必是大小可調整的。
該排序算法是一個經過修改的合並排序算法,其中 如果低子列表中的最高元素小魚高子列表中的最低元素,則忽略合並。此算法提供可擺正的n log(n)性能。此實現將指定列表轉儲到一個數組中,並對數組進行排序,在重置數組中相應位置處每個元素的列表上進行迭代。這避免了由於試圖原地對鏈接列表進行排序而產生的n² log(n)性能。
拋出 ClassCastException ---如果列表包含不可相互比較的元素 例如 字符串和整數。 拋出 UnsupportedOperationException ---如果指定列表的列表迭代器不支持set操作。
public static <T> void sort(List<T> list , Comparable<? supper T> c)
根據指定比較器產生的順序對指定列表進行排序。此列標內的所有元素都必須可使用指定比較器相互比較 也就是說 對於列表中的任意 e1 和e2元素,c.compare(e1,e2)不得拋出ClassCastException。
次排序被保證是穩定的,不會因調用sort而對相等的元素進行重新排序。
排序算法是一個經過修改的合並排序算法 其中 如果低子列表中的最高元素小魚高子列表中的最低元素,則忽略合並。此算法提供可擺正的n log(n)性能。指定列表必須是可修改的,但不鄙視可大小調整的。此實現將指定列表轉儲到一個數組中,並對數組進行排序,在重置數組中相應位置每個元素的列表上進行迭代。這避免了由於試圖原地對鏈接列表進行排序而產生的n? log(n)性能。
拋出 ClassCastException ---如果列表包含不可使用指定比較器相互比較的元素。 拋出 UnsupportedOperationException ---如果指定列表的列表迭代器不支持set操作。
接口 Comparator<T>
public interface Comparator<T>
強行對某個對象 collection 進行整體排序的比較函數。可以將Comparator傳遞給sort方法 例如:Collections.sort或Arrays.sort,從而允許在排序順序上實現精確控制。還可以使用Comparator來控制某些數據結構 (如 有序set 或有序映射) 的順序,或者為那些沒有自然順序的對象collection提供排序。
當且僅當對於一組元素s中的每個e1和e2而言,c.compare(e1,e2)==0 與 e1..equals(e2)具有相等的布爾值時,Comparator c 強行對s進行的排序才叫做與equals一致的排序。
當使用具有與equals不一致的強行排序能力的Comparator 對有序set或有序映射進行排序時,應該小心謹慎。假定一個帶顯示Comparator c的有序set或有序映射與set S中抽取出來的元素或鍵一起使用。如果c強行對s進行的排序是與equals 不一致的,那么有序set或有序映射將是行為"怪異的"。尤其是有序set或有序映射 將違背根據equals 所定義的set或映射的常規協定。
例如 假定使用Comparator c 將滿足(a.equals(b) && c.compare(a,b) !=0)的兩個元素 a和b添加到一個空的TreeSet中,則第二個add將返回true(TreeSet的大小將會增加),因為從TreeSet的角度來看,a,b是不相等的,即使這與 Set.add方法的規范相反。
注:通常來說,讓Comparator也實現java.io.Serializable 是一個好主意 ,因為他們在序列化的數據結構 像TreeSet 、TreeMap中可用作排序方法。為了成功地序列化數據結構,Comparator必須實現Serializable。
在算數上,定義給定Comparator c 對給定對象set s實施強行排序的關系為:
{(x,y)such that c.compare(x,y)<=0}
在整體排序的系數(quotient)為
{(x,y)such that c.compare(x,y)==0}
它直接遵循compare 的協定,系數是s上的等價關系,強行排序時s上的整體排序。當我們說c強行對s的排序時與equals 一致是,意思是說排序的系數是對象的equals(Object)方法所定義的等價關系:
{(x,y)such that x,equals(y)}
Comparator的方法
int compare(T o1,T o2)
比較用來排序的兩個參數。根據第一個參數小於等於或大於第二個參數分別返回負整數、零、或正整數。
拋出 ClassCastException --- 如果參數的類型不允許此Comparator 對他們進行比較。
boolean equals(Object obj)
指示某個其他對象是否"等於"此Comparator。此方法必須遵守Object.equals(Object)的常規協定。此外,僅當指定的對象也是一個Comparator,並且強行實施與此Comparator相同的排序時,此方法才返回true。
注意,不重寫Object.equals(Object)方法總是安全的。然而,在某些情況下,重寫此方法可以允許程序確定兩個不同的Comparator是否強行實施了相同的排序,從而提高性能。