熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

java中對於復雜對象排序的模型及其實現

2013-11-23 18:53:35  來源: Java核心技術 

  排序是編程中經常要碰到的問題如果只是一般的數據庫數據那麼我們完全可以用數據sql語言來排序但有的時候情況並不是這樣在一些特殊情況下我們不得不自己在java中寫一些排序而通常排序是一件讓程序員非常惱火的事情特別是那些可以讓用戶自由選擇排序規則的情況想想就頭疼今天正好公司一個組件就碰到了這樣的情況下面我說一下怎麼來完成並且實現排序

  首先讓我們來看一下用戶需求是怎麼樣(為了更容易理解我將用戶需求簡化了一下實際情況可能更復雜) 一個財務人員需要查詢公司內所有用戶的數據信息對於查詢出來的結果該用戶能夠自己定義排序規則(例如他希望對用戶姓名進行升序同時對工資進行降序並且對生日進行升序也許有人會說這個直接用sql就能完成請注意這個用例是我簡化了的真實的情況會非常復雜同時並不是一條sql就能解決的)

  對於這個需求我們第一個想到的應該有一個員工信息對象(Employee)用戶姓名工資生日都是這個對象的屬性用戶的查詢結果就是Employee對象的List我們知道java本身提供了一個非常好的對於List的排序方法Collectionssrot(List <T> list Comparator  c ) 如果我們有一個針對Employee的Comparator對象他知道如何對兩個Employee對象進行比較根據比較結果來決定Employee對象的排列順序這樣就能夠實現用戶的需求第二點用戶能夠自己定義一組排序規則那麼我們應該有一個EmployeeSortOrder對象它包含了所有用戶所定義的每一條規則從需求理解我們可以知道這些規則就是對Employee對象中某些屬性定義他的排序規則(升序或者降序)那麼我們可以通過引入一個(EmployeeOrder)對象來指明具體Employee對象中有的屬性如何來排序這裡需要包括這些屬性的類型應該對於不同的屬性比較方式是不一樣的需求分析到這裡我們基本就可以得到一個實現排序的模型

  下面我們來看一下具體代碼:

  Employee對象一個標准的javabean對象實際情況可能會是一個更加復雜的對象

  /** */ /**

  *

  */

  package  comdemosort;

  import  javamathBigDecimal; import  javautilDate;

  /** */ /**

  * @author Administrator

  *

  */

  public   class  Employee  {

  private Long employeeId;

  private String firstName;

  private String lastName;

  private Date birthday;

  private BigDecimal payment;

  public  Date getBirthday()  {

  return birthday;

  }

  public   void  setBirthday(Date birthday)  { this birthday  =  birthday;

  }

  public  Long getEmployeeId()  {

  return employeeId;

  }

  public   void  setEmployeeId(Long employeeId)  { this employeeId  =  employeeId;

  }

  public  String getFirstName()  {

  return firstName;

  }

  public   void  setFirstName(String firstName)  { this firstName  =  firstName;

  }

  public  String getLastName()  {

  return lastName;

  }

  public   void  setLastName(String lastName)  { this lastName  =  lastName;

  }

  public  BigDecimal getPayment()  {

  return payment;

  }

  public   void  setPayment(BigDecimal payment)  { this payment  =  payment;

  }

  @Override

  public   int  hashCode()  {

  // TODO Autogenerated method stub

  return   super hashCode();

  }

  @Override

  public  String toString()  {

  StringBuffer buf = new StringBuffer();

  bufappend( [ ); bufappend( employeeId= + employeeId)append(   ); bufappend( firstName= + firstName)append(   ); bufappend( lastName= + lastName)append(   ); bufappend( birthday= + birthday)append(   ); bufappend( payment= + payment); bufappend( ] ); return  buftoString();

  }

  }

  Employee的complarator對象他調用了ISortOrder來獲得比較結果這樣我們就能夠將具體的比較算法留到下層來實現一旦Employe的比較規則改變這個類也不需要在理會了

  /** */ /**

  *

  */

  package  comdemosort;

  import  javautilComparator;

  /** */ /**

  * @author Administrator

  *

  */

  public   class  EmployeeComparator  implements  Comparator  {

  ISortOrder sortOrder;

  public  EmployeeComparator(ISortOrder sortOrder) { this sortOrder = sortOrder;

  }

  /**/ /* (nonJavadoc)

  * @see javautilComparator#compare(javalangObject javalangObject)

  */

  public   int  compare(Object arg Object arg { return  pare(argarg);

  }

  }

  /** */ /**

  *

  */

  package  comdemosort;

  /** */ /**

  * @author Administrator

  *

  */

  public   interface  ISortOrder  {

  public   int  compare(Object arg Object arg);

  }

  具體的排序規則對象這個對象記錄了Employee對象中具體屬性的排序規則和屬性類型如果用戶定義了多條規則那麼沒一條規則就應該對於一個實例

  /** */ /**

  *

  */

  package  comdemosort;

  /** */ /**

  * @author Administrator

  *

  */

  public   class  EmployeeOrder  {

  public final static int _LONG = ;

  public final static int _STRING = ;

  public final static int _DATE = ;

  public final static int _BIGDECIMAL = ;

  private String propertyName;

  private boolean isAsc;

  private int dataType;

  public  EmployeeOrder(String propertyName  boolean  isAsc int  dataType)  { this propertyName  =  propertyName; this isAsc  =  isAsc; this dataType = dataType;

  }

  public   boolean  isAsc()  {

  return isAsc;

  }

  public   void  setAsc( boolean  isAsc)  { this isAsc  =  isAsc;

  }

  public  String getPropertyName()  {

  return propertyName;

  }

  public   void  setPropertyName(String propertyName)  { this propertyName  =  propertyName;

  }

  public   int  getDataType()  {

  return dataType;

  }

  public   void  setDataType( int  dataType)  { this dataType  =  dataType;

  }

  }

  這裡是重點這個對象知道如何根據order規則來排序comparator就是調用這個對象的compare方法來獲得比較結果由於 EmployeeOrder對象中定義了對象屬性的排序方法所以這個對象中使用的java的反射來獲得具體屬性值並根據不同的屬性類型進行比較如果一共有條比較規則那麼在比較個Employee對象是先從第一個規則開始比較如果比較出來一樣那麼在進行第二個規則的比較否則退出比較由於本人很懶所以只對其中的一部分屬性類型給出了比較方法並沒有實現所有數據類型的比較大家可以自己實現呵呵

  /** */ /**

  *

  */

  package  comdemosort;

  import  javalangreflectField; import  javamathBigDecimal; import  javautilList;

  /** */ /**

  * @author Administrator

  *

  */

  public   class  EmployeeSortOrder  implements  ISortOrder  {

  private List < EmployeeOrder > orders;

  public  EmployeeSortOrder(List < EmployeeOrder >  orders)  { this orders  =  orders;

  }

  public   int  compare(Object arg Object arg {

  int result = ;

  try   {

  Employee e = (Employee) arg;

  Employee e = (Employee) arg;

  for  (EmployeeOrder order : orders)  { Object v = getVaule(eordergetPropertyName()); Object v = getVaule(eordergetPropertyName()); result = sort(vvordergetDataType()); if ( ! orderisAsc()) {

  result *= ;

  }

  if (result != ) {

  break ;

  }

  }

  }   catch  (Exception e)  {

  // TODO: handle exception

  }

  return result;

  }

  private   int  sort(Object vObject v int  dataType) {

  int result = ;

  switch  (dataType)  { case  EmployeeOrder_STRING:

  String s = (String)v;

  String s = (String)v;

  result = pareTo(s);

  break ;

  case  EmployeeOrder_BIGDECIMAL:

  BigDecimal d = (BigDecimal)v;

  BigDecimal d = (BigDecimal)v;

  result = pareTo(d);

  break ;

  case  EmployeeOrder_LONG:

  Long l = (Long)v;

  Long l = (Long)v;

  result = pareTo(l);

  break ;

  default :

  result = ;

  break ;

  }

  return result;

  }

  private  Object getVaule(Object objString propertyName) {

  Object result = null ;

  try   { Class clazz  =  objgetClass(); Field field  =  clazzgetDeclaredField(propertyName); fieldsetAccessible( true ); result  =  fieldget(obj); }   catch  (Exception e)  { eprintStackTrace();

  }

  return result;

  }

  }

  沒多說的測試類

  package  comdemosort;

  import  javamathBigDecimal; import  javautilArrayList; import  javautilCalendar; import  javautilCollections; import  javautilDate; import  javautilList;

  import  junitframeworkTestCase;

  public   class  EmployeeSortTest  extends  TestCase {

  private List < Employee > employeeList;

  @Override

  protected   void  setUp()  throws  Exception  { super setUp();

  Employee e;

  Date date;

  Calendar cal = CalendargetInstance();

  employeeList = new ArrayList < Employee > ();

  for  ( int  i = ;i < ;i ++ )  {

  e = new Employee();

  if ( == i % )

  caladd(CalendarDATE  ); date = calgetTime(); esetBirthday(date); esetEmployeeId(LongvalueOf(i)); esetFirstName( firstName + i / ); esetLastName( LastName + i * ); esetPayment( new  BigDecimal(i % )); employeeListadd(e);

  }

  }

  @Override

  protected   void  tearDown()  throws  Exception  { super tearDown();

  }

  public   void   testSort() {

  List < EmployeeOrder > orders = new ArrayList < EmployeeOrder > ();

  EmployeeOrder order = new  EmployeeOrder( firstName false EmployeeOrder_STRING); ordersadd(order); order = new  EmployeeOrder( employeeId false EmployeeOrder_LONG); ordersadd(order);

  ISortOrder sortOrder = new EmployeeSortOrder(orders);

  EmployeeComparator comparator = new EmployeeComparator(sortOrder);

  Collectionssort(employeeListcomparator); for  (Employee employee : employeeList)  { Systemoutprintln(employee);

  }

  }

  }


From:http://tw.wingwit.com/Article/program/Java/hx/201311/25943.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.