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());
}
}
這樣子就可以實現排序功能了。
哈哈,執行結果正確!!!