Java SortedSet為什么可以實現自動排序?


Set中的SortedSet(SortedSet為TreeSet的實現接口),它們之間的繼承關系如下:

java.util.Set;

java.util.SortedSet; 

java.util.TreeSet; 

SortedSet中的元素無序不可重復,但是存進去的元素可以按照元素大小順序自動排序。結合以下代碼來看:

 

import java.util.*;
import java.text.*;
public class SortedSetTest01{
 public static void main(String[] args)throws Exception{
   SortedSet ss=new TreeSet();
   //數字類
   ss.add(12);
   ss.add(23);
   ss.add(45);
   ss.add(39);
   ss.add(45);
   Iterator it=ss.iterator();
   while(it.hasNext()){
     System.out.println(it.next());
   }
   //String類
   SortedSet str=new TreeSet();
   str.add("JACK");
   str.add("TOM");
   str.add("KING");
   str.add("SUN");
   it=str.iterator();
   while(it.hasNext()){
     System.out.println(it.next());
   }
   //日期類
   String st1="2003-08-12";
   String st2="2004-09-17";
   String st3="2003-04-12";
   String st4="2013-09-04";
   
   SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
   Date t1=sdf.parse(st1);
   Date t2=sdf.parse(st2);
   Date t3=sdf.parse(st3);
   Date t4=sdf.parse(st4);
   
   SortedSet times=new TreeSet();
   times.add(t1);
   times.add(t2);
   times.add(t3);
   times.add(t4);
   
   it=times.iterator();
   while(it.hasNext()){
     Object element=it.next();
     if(element instanceof Date){
       Date d=(Date)element;
       System.out.println(sdf.format(d));
     }
   }
 }
}

 

編譯運行后輸出:

 

12
23
39
45
JACK
KING
SUN
TOM
2003-04-12
2003-08-12
2004-09-17
2013-09-04

 

以上代碼展示了存在SortedSet中的元素可以按照元素大小進行排序,這些元素可以是數字類,字符串類或日期類等。既然知道了SortedSet的這一特性,那么SortedSet集合存儲元素為什么可以自動排序?

 

在上面的代碼中我們實現了SortedSet中的數字,字符串和日期類的自動排序,那么如果我們自定義幾個User類型對象,然后把它們添加到SortedSet集合中去,可以實現像上面那樣的自動排序嗎?試一下。

 

import java.util.*;
public class SortedSetTest02{
 public static void main(String[] args){
   SortedSet users=new TreeSet();
   User u1=new User(12);
   User u2=new User(16);
   User u3=new User(23);
   User u4=new User(32);
   User u5=new User(43);
   
   users.add(u1);
   users.add(u2);
   users.add(u3);
   users.add(u4);
   users.add(u5);
   Iterator it=users.iterator();
   while(it.hasNext()){
     System.out.println(it.next());
   }
 }
}
class User{
 int age;
 User(int age){
   this.age=age;
 }
 public String toString(){
   return "User[age="+age+"]";
 }
}

 

編譯通過,運行后出錯,輸出:

Exception in thread "main" java.lang.ClassCastException: User cannot be cast to java.lang.Comparable

at java.util.TreeMap.compare(Unknown Source)

at java.util.TreeMap.put(Unknown Source)

at java.util.TreeSet.add(Unknown Source)

at SortedSetTest02.main(SortedSetTest02.java:14)

User cannot be cast to java.lang.Comparable,也就是說User不可以轉變成可比較的類型。所以User必須實現Comparable接口(也就是第一個程序例子中數字,字符串,日期底層已經實現了Comparable接口),即class User implements Comparable{ }。我們知道一個類實現一個接口就實現了這個接口的所有方法,SortedSet集合中的元素之所以可以自動排序,是因為使用add()方法添加進去的元素實現了Comparable接口中的CompareTo()方法。

上述代碼中,如果我們給定一個需求,按照User的年齡排序,那么就需要編寫一個比較規則,

 

public int compareTo(Object o){
   //編寫一個比較規則
   int age1=this.age;
   int age2=((User)o).age;
   return age1-age2;
 }

 

compareTo的用法為u1.compareTo(u2),this為u1,括號里的參數o為u2,因為括號里的參數類型為Object類型,而Object類型沒有age這個屬性,所以必須把o強制類型轉換為User類型,即(User)o。修改之后的整體代碼如下:

 

import java.util.*;
public class SortedSetTest02{
 public static void main(String[] args){
   SortedSet users=new TreeSet();
   User u1=new User(12);
   User u2=new User(16);
   User u3=new User(23);
   User u4=new User(32);
   User u5=new User(43);
   
   users.add(u1);
   users.add(u2);
   users.add(u3);
   users.add(u4);
   users.add(u5);
   Iterator it=users.iterator();
   while(it.hasNext()){
     System.out.println(it.next());
   }
 }
}
class User implements Comparable{
 int age;
 User(int age){
   this.age=age;
 }
 public String toString(){
   return "User[age="+age+"]";
 }
 //實現java.lang.Comparable;接口中的compareTo方法
 //該方法程序員負責實現,SUN提供的程序已經調用了該方法
 //需求:按照User的年齡排序
 public int compareTo(Object o){  //u1.compareTo(u2)
   //編寫一個比較規則
   int age1=this.age;   
   int age2=((User)o).age;
   return age1-age2;
 }
}

 

編譯運行后輸出:

 

User[age=12]
User[age=16]
User[age=23]
User[age=32]
User[age=43]

 

除此之外,還有另一種方法實現SortedSet集合排序:使用java.util.Comparator;來單獨編寫一個比較器,創建TreeSet集合的時候提供這個比較器,即SortedSet products=new TreeSet(new ProductComparator()); 代碼如下:

 

import java.util.*;
public class SortedSetTest03{
 public static void main(String[] args){
   //創建TreeSet集合的時候提供一個比較器
   SortedSet products=new TreeSet(new ProductComparator());
   Product p1=new Product(3.4);
   Product p2=new Product(4.0);
   Product p3=new Product(3.6);
   Product p4=new Product(7.6);
   Product p5=new Product(3.7);
   
   products.add(p1);
   products.add(p2);
   products.add(p3);
   products.add(p4);
   products.add(p5);
   
   Iterator it=products.iterator();
   while(it.hasNext()){
     System.out.println(it.next());
     }
 }
}
class Product{
 double price;
 Product(double price){
   this.price=price;
 }
 public String toString(){
   return price + "";
 }
}
//單獨編寫一個比較器
class ProductComparator implements Comparator{
 //需求:按照商品價格排序
 public int compare(Object o1,Object o2){
   double price1=((Product)o1).price;
   double price2=((Product)o2).price;
   if (price1==price2){
     return 0;
   }else if(price1>price2){
     return -1;
   }
   return 1;
 }
}

 

編譯運行后輸出:

 

7.6
4.0
3.7
3.6
3.4

wx搜索“程序員考拉”,專注java領域,一個伴你成長的公眾號!



免責聲明!

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



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