1. 程式人生 > >Java程式設計之TreeSet排序兩種解決方法(1)元素自身具備比較功能,元素需要實現Comparable介面覆蓋compare(2)建立根據自定義Person類的name進行排序的Comparator

Java程式設計之TreeSet排序兩種解決方法(1)元素自身具備比較功能,元素需要實現Comparable介面覆蓋compare(2)建立根據自定義Person類的name進行排序的Comparator

       當很多人問我讀研到底好不好的時候,我總是說上研很苦逼,讀完研之後都不知道自己能不能找到工作,所以不建議同學們讀研~即使要讀也讀一個985或者211的研究生,這是我肺腑之言。但還有一半我沒說完,讀研的時候你可能會找到你喜歡的活動,會遇到一些願意和你一起玩的玩伴,在讀研期間可以很任性的在想玩耍的時候就去玩兒,這是讀研的福利,很高興我能遇到。好了開始技術!

      學習Java,肯定會學到集合,然後遇到TreeSet,我現在就遇到了它。同時使用它的時候遇到一些問題。首先說說什麼是TreeSet。TreeSet是Set 的子介面,而Set介面的元素不可重複、無序的特性TreeSet也是具備的。另外,TreeSet還具有可以對集合中的元素進行指定順序的排序的功能。

     這個功能實現的基本原理就是,當存放元素的時候進行比較,比較之後再存入。對於普通的字串它可以完美的實現排序功能:

public static void demo1() {
		TreeSet ts = new TreeSet();
		ts.add("abc");
		ts.add("nba");
		ts.add("linweieran");
		ts.add("cba");
		
		Iterator it = ts.iterator();
		while(it.hasNext()){
			System.out.println(it.next());
		}
	}
執行結果如下:

執行結果正確。

但當我向TreeSet集合中儲存自定義的Person物件是就會發生錯誤!

public static void main(String[] args) {				
		
		TreeSet ts = new TreeSet(new CompareByName()) ;
		
		ts.add(new Person("linweieran",24));
		ts.add(new Person("linweieran1",23)); //bean.Person cannot be cast to java.lang.Comparable
					
		ts.add(new Person("linweieran2",22));
		ts.add(new Person("weixiaobao",25));
		ts.add(new Person("linweieran",24));
		
		Iterator  it = ts.iterator();
		while(it.hasNext()){
			Person p = (Person)it.next();
			System.out.println(p.getName()+":"+p.getAge());
		}

	}
發生這樣的錯誤:


查文件會找到這樣的解釋:Comparable此介面強行對實現它的每個類的物件進行強行排序,這種排序成為自然排序,類的compareTo 方法就是它的自然比較方法。所以為了實現該功能就有兩個方法

     TreeSet對元素進行排序的方式一:讓元素自身具備比較功能,元素需要實現Comparable介面,覆蓋compareTo()方法;簡而言之就是在Person類中繼承Comparable介面,並重寫compareTo()方法。

public class Person implements Comparable {
	
	private String name;
	private int age;
	
	//alt+shift+s
	
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	
	/*
	 * 以Person物件的年齡進行從小到大的排序。
	 */
	@Override
	public int compareTo(Object o) {
		//進行比較,
		Person p = (Person)o;
		/*
		if(this.age>p.age)
			return 1;
		if(this.age<p.age)
			return -1;
		if(this.age==p.age){
			//姓名怎麼比較-----
			return this.name.compareTo(p.name);
			
		}
		*/
		System.out.println(this.name+"---compareTo---");
		int temp= this.age-p.age;
		return temp==0?this.name.compareTo(p.name):temp;
		
		
	}
編碼思路是:先對年齡進行比較,如果年齡相容再對姓名(String)進行比較,最後可以簡約成三行程式碼!!

這樣子就可以實現排序功能。

      但是,使用上述的方式有一個問題,如果Person類不是自己寫的,我們就無法在Person類中進行修改實現該功能,如果是這種情況怎麼辦呢?這就需要另一種方式了!

       TreeSet集合的第二種排序方式:讓集合自身具備比較功能,定義一個類實現Comparator介面,覆蓋Comparat方法。建構函式TreeSet(Comparator c)的比較器。

       首先我們需要寫一個類,該類繼承Comparator,同時實現按姓名排序的方法。

public class CompareByName implements Comparator {

	@Override
	public int compare(Object o1, Object o2) {
		
		System.out.println("CompareByName----");
		Person p1=(Person)o1;
		Person p2=(Person)o2;
		
		int temp = p1.getName().compareTo(p2.getName());
		
		return temp==0?p1.getAge()-p2.getAge():temp;
	}
	
}
      然後,在建立TreeSet的時候需要直接用到TreeSet(Comparator c)的建構函式。
public static void main(String[] args) {		
		
		/*
		 * 以Person物件的年齡進行從小到大的排序。
		 */
		
		TreeSet ts = new TreeSet(new CompareByName()) ;//new CompareByName()
		
		ts.add(new Person("linweieran",24));
		ts.add(new Person("linweieran1",23)); //bean.Person cannot be cast to java.lang.Comparable
					
		ts.add(new Person("linweieran2",22));
		ts.add(new Person("weixiaobao",25));
		ts.add(new Person("linweieran",24));
		
		Iterator  it = ts.iterator();
		while(it.hasNext()){
			Person p = (Person)it.next();
			System.out.println(p.getName()+":"+p.getAge());
		}

	}
這樣子就可以實現排序功能了。

哈哈,執行結果正確!!!