關於List 的排序


/**
 * @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是否強行實施了相同的排序,從而提高性能。

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM