知识大全 java中对于复杂对象排序的模型及其实现

Posted 规则

篇首语:会挽雕弓如满月,西北望,射天狼。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 java中对于复杂对象排序的模型及其实现相关的知识,希望对你有一定的参考价值。

  排序是编程中经常要碰到的问题 如果只是一般的数据库数据那么我们完全可以用数据sql语言来排序 但有的时候情况并不是这样 在一些特殊情况下我们不得不自己在java中写一些排序 而通常排序是一件让程序员非常恼火的事情 特别是那些可以让用户自由选择排序规则的情况 想想就头疼 今天正好公司一个组件就碰到了这样的情况 下面我说一下怎么来完成并且实现排序

  首先让我们来看一下用户需求是怎么样(为了更容易理解我将用户需求简化了一下 实际情况可能更复杂) 一个财务人员需要查询公司内所有用户的数据信息 对于查询出来的结果该用户能够自己定义排序规则(例如 他希望对用户姓名进行升序 同时对工资进行降序 并且对生日进行升序 也许有人会说这个直接用sql就能完成 请注意 这个用例是我简化了的 真实的情况会非常复杂 同时并不是一条sql就能解决的)

  对于这个需求我们第一个想到的应该有一个员工信息对象(Employee) 用户姓名 工资 生日都是这个对象的属性 用户的查询结果就是Employee对象的List 我们知道java本身提供了一个非常好的对于List的排序方法Collections srot(List <T> list Comparator  c ) 如果我们有一个针对Employee的Comparator对象他知道如何对两个Employee对象进行比较 根据比较结果来决定Employee对象的排列顺序 这样就能够实现用户的需求 第二点 用户能够自己定义一组排序规则 那么我们应该有一个EmployeeSortOrder对象 它包含了所有用户所定义的每一条规则 从需求理解我们可以知道这些规则就是对Employee对象中某些属性定义他的排序规则(升序或者降序) 那么我们可以通过引入一个(EmployeeOrder)对象来指明具体Employee对象中有的属性如何来排序 这里需要包括这些属性的类型 应该对于不同的属性比较方式是不一样的 需求分析到这里我们基本就可以得到一个实现排序的模型

  下面我们来看一下具体代码:

  Employee对象 一个标准的javabean对象 实际情况可能会是一个更加复杂的对象

  /** */ /**

  *

  */

  package  demo sort;

  import  java math BigDecimal; import  java util Date;

  /** */ /**

  * @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 Auto generated method stub

  return   super hashCode();

  

  @Override

  public  String toString() 

  StringBuffer buf = new StringBuffer();

  buf append( [ ); buf append( employeeId= + employeeId) append(   ); buf append( firstName= + firstName) append(   ); buf append( lastName= + lastName) append(   ); buf append( birthday= + birthday) append(   ); buf append( payment= + payment); buf append( ] ); return  buf toString();

  

  

  Employee的plarator对象 他调用了ISortOrder来获得比较结果 这样我们就能够将具体的比较算法留到下层来实现 一旦Employe的比较规则改变 这个类也不需要在理会了

  /** */ /**

  *

  */

  package  demo sort;

  import  java util Comparator;

  /** */ /**

  * @author Administrator

  *

  */

  public   class  EmployeeComparator  implements  Comparator 

  ISortOrder sortOrder;

  public  EmployeeComparator(ISortOrder sortOrder) this sortOrder = sortOrder;

  

  /**/ /* (non Javadoc)

  * @see java util Comparator#pare(java lang Object java lang Object)

  */

  public   int  pare(Object arg Object arg )  return  pare(arg arg );

  

  

  /** */ /**

  *

  */

  package  demo sort;

  /** */ /**

  * @author Administrator

  *

  */

  public   interface  ISortOrder 

  public   int  pare(Object arg Object arg );

  

  具体的排序规则对象 这个对象记录了Employee对象中具体属性的排序规则和属性类型 如果用户定义了多条规则那么没一条规则就应该对于一个实例

  /** */ /**

  *

  */

  package  demo sort;

  /** */ /**

  * @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规则来排序 parator就是调用这个对象的pare方法来获得比较结果 由于 EmployeeOrder对象中定义了对象属性的排序方法 所以这个对象中使用的java的反射来获得具体属性值 并根据不同的属性类型进行比较 如果一共有 条比较规则 那么在比较 个Employee对象是先从第一个规则开始比较 如果比较出来一样 那么在进行第二个规则的比较 否则退出比较 由于本人很懒所以只对其中的一部分属性类型给出了比较方法 并没有实现所有数据类型的比较 大家可以自己实现 呵呵

  /** */ /**

  *

  */

  package  demo sort;

  import  java lang reflect Field; import  java math BigDecimal; import  java util List;

  /** */ /**

  * @author Administrator

  *

  */

  public   class  EmployeeSortOrder  implements  ISortOrder 

  private List < EmployeeOrder > orders;

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

  

  public   int  pare(Object arg Object arg ) 

  int result = ;

  try  

  Employee e = (Employee) arg ;

  Employee e = (Employee) arg ;

  for  (EmployeeOrder order : orders)  Object v = getVaule(e order getPropertyName()); Object v = getVaule(e order getPropertyName()); result = sort(v v order getDataType()); if ( ! order isAsc())

  result *= ;

  

  if (result != )

  break ;

  

  

     catch  (Exception e) 

  // TODO: handle exception

  

  return result;

  

  private   int  sort(Object v Object 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 obj String propertyName)

  Object result = null ;

  try   Class clazz  =  obj getClass(); Field field  =  clazz getDeclaredField(propertyName); field setAccessible( true ); result  =  field get(obj);    catch  (Exception e)  e printStackTrace();

  

  return result;

  

  

  没多说的 测试类

  package  demo sort;

  import  java math BigDecimal; import  java util ArrayList; import  java util Calendar; import  java util Collections; import  java util Date; import  java util List;

  import  junit framework TestCase;

  public   class  EmployeeSortTest  extends  TestCase

  private List < Employee > employeeList;

  @Override

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

  Employee e;

  Date date;

  Calendar cal = Calendar getInstance();

  employeeList = new ArrayList < Employee > ();

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

  e = new Employee();

  if ( == i % )

  cal add(Calendar DATE   ); date = cal getTime(); e setBirthday(date); e setEmployeeId(Long valueOf(i)); e setFirstName( firstName + i / ); e setLastName( LastName + i * ); e setPayment( new  BigDecimal(i % )); employeeList add(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); orders add(order); order = new  EmployeeOrder( employeeId false EmployeeOrder _LONG); orders add(order);

  ISortOrder sortOrder = new EmployeeSortOrder(orders);

  EmployeeComparator parator = new EmployeeComparator(sortOrder);

  Collections sort(employeeList parator); for  (Employee employee : employeeList)  System out println(employee);

  

  

cha138/Article/program/Java/hx/201311/25943

相关参考

根据菲茨与波斯纳三阶段模型,对于士兵装卸枪支技能形成的各阶段,下列排序正确的是__。①闭着眼睛装卸枪支②仔细研究枪

根据菲茨与波斯纳三阶段模型,对于士兵装卸枪支技能形成的各阶段,下列排序正确的是_____。①闭着眼睛装卸枪支②仔细研究枪支的使用说明和图纸③选择合适的两部分连接,完成组装A、①②③B、②①③C、①③②

知识大全 Java对象池技术的原理及其实现

Java对象池技术的原理及其实现  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  摘要本文在分析对

知识大全 Java语言深入 多线程程序模型研究

Java语言深入多线程程序模型研究  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  多线程是较复杂

知识大全 基于角色模型的Java开发

基于角色模型的Java开发  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  对于软件开发人员而言调

知识大全 Eclipse插件开发中的Java项目模型

Eclipse插件开发中的Java项目模型  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Jav

知识大全 java反射机制

  JAVA反射机制是在运行状态中对于任意一个类都能够得到这个类的所有属性和方法;对于任意一个对象都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制 

电力工程应用软件中三维模型建立的细度要求?

  二锅头  1在建立三维模型前应做模型总体设计,根据模型的用途,确定模型内容。  2模型中主要内容应满足:  (1)物理对象的轮廓描述,其外形接口尺寸应与施工图实际尺寸相一致;  (2)物理对象的详

电力工程应用软件中三维模型建立的细度要求?

  二锅头  1在建立三维模型前应做模型总体设计,根据模型的用途,确定模型内容。  2模型中主要内容应满足:  (1)物理对象的轮廓描述,其外形接口尺寸应与施工图实际尺寸相一致;  (2)物理对象的详

知识大全 如何给一个对象排序

  当我们排序的对象不止是简单的数据类型的时候  我们可以通过实现Comparable和Comparator接口来完整对对象的排序  Comparable和Compartor的区别?  Compara

知识大全 java以及其相关性应用

  马上就要开始C++编程对于java掐指算来去年月份开始到现在一年有余了经历一年的java生涯中同时在加上前段时间的ibm的培训不由想为自己或者别人总结一下java以及其相关性的东西本人觉得这篇文章