关于排序
				
				
						
								
								
								
						
				
		
		
				众所周知,如果需要在
				Java 
				中使用排序方法,那么就需要实现
				
				
						
Comparable 
				接口。
				
 
		
				public interface java.lang.Comparable {
              public int compareTo(Object o);
     } 
				
						
						
				
		
		
		
		
		
				    Comparable 
				接口很简单,因为它只有一个方法;然而如果你需要根据多
个属性对对象进行排序,那么实现
				compareTo 
				方法就会变得很复杂。
				
						
						
				
		
		
				      
				下边就是一个摘自
				
				
				Jakarta Commons cookbook
				
				
				的例子:
				
				
				
						
						
				
		
		
				
						
package com.discursive.jccook.collections.compare; 
		
		
				
						
import java.util.*; 
		
		
				
						
import org.apache.commons.lang.StringUtils; 
		
		
				
						
import org.apache.commons.collections.comparators.ReverseComparator; 
		
		
				
						 
				
		
		
				public class BookComparator implements Comparator { 
		
		
				
						   
public int compare(Object o1, Object o2) { 
		
		
				
						        
   int comparison = -1; 
		
		
				
						       
    if( o1 instanceof Book && o2 instanceof Book ) { 
		
		
				
						
								
            Book b1 = (Book) o1; 
		
		
				
						
								
            Book b2 = (Book) o2; 
		
		
				
						
								
             String b1Name = b1.getName( ); 
		
		
				
						
								
             String b2Name = b2.getName( ); 
		
		
				
						
								
             String b1Author = b1.getAuthor( ); 
		
		
				
						
								
             String b2Author = b2.getAuthor( ); 
		
		
				
						
								
            if( StringUtils.isNotEmpty( b1Name ) && 
		
		
				
						
								
               StringUtils.isNotEmpty( b2Name ) ) { 
		
		
				
						
								
       
						         comparison = b1Name.compareTo( b2Name ); 
		
		
				
						
								
            } 
		
		
				
						
								
            if( comparison == 0 && 
		
		
				
						
								
                StringUtils.isNotEmpty( b1Author ) && 
		
		
				
						
								
                StringUtils.isNotEmpty( b2Author ) ) { 
		
		
				
						
								
                comparison = b1Author.compareTo( b2Author ); 
		
		
				
						
								
            }   
		
		
				
						
								
        } 
		
		
				
						
								
        return comparison; 
		
		
				
						
								
    } 
		
		
				
						
} 
		
		
				
						
   该事例是对一个称为
				book 
				的
				bean 
				进行排序,将会根据
				name 
				和
				author 
				
						
						
两个属性进行排序。当我们使用的时候,就可以类似于以下的形式。
				
						
						
				
		
		
				
						
     Arrary.sort(books,BookComparator) 
				或者
				collections.sort
(books,BookComparator). 
				当中的两个参数是要排序的数组或者
				list 
				以及使
用的
				Comparator 
				。下边主要说的就是怎样构造
				Comparator 
				。
				
						
						
				
		
		
				
						
本文的是展示怎样使用
				commons 
				的组件,来完成
				Comparator 
				的构造。
				
						
						
				
		
		
				
						
								
对单一
				
				
						bean 
				
				
						的单个属性排序
				
				
						
								
								
						
				
		
		
				
						
      
				现在如果我们只是想对
				bean 
				中的一个属性进行排序的话。那么只需要构造
出一个
				BeanComparator 
				的实例就可以了
				. 
		
		
				
						
形式如下:
 
		
				private BeanComparator comparator = new BeanComparator("name"); 
		
		
				
						
      
				这样子我们就构造出了一个根据
				”name” 
				属性来对集合中的
				bean 
				进行排
序的比较器。当集合中的
				bean 
				有
				name 
				这个属性的时候,那么排序时就会依照
这个排序器来调整集合中
				bean 
				的顺序。
				
						
						
				
		
		
				
						
    BeanComparator 
				是
				BeanUtils API 
				中的一个类,使用它可以很简单地根
据
				bean 
				的属性对
				Bean 
				类进行排序。
				
						
								
								
						
				
		
		
				
						
      
				需要说明的是这个比较器只是对符合
				javabean 
				规范的类进行比较,如果类
中没有这个属性或者属性没有
				get 
				和
				set 
				方法,那么在比较的时候就会抛出
				
						
						
ClassCastException 
				。
				
						
						
				
		
		
				
						
								
装饰比较器
				
				
						
								
								
						
				
		
		
				
						
      
				上边生成的比较器是带有一些默认的排序规则的,比如按着自然顺序排列,
当遇到字符串的值是“”的时候就排列在前端。下边我将说明怎么改变这种默认
的规则。
				
						
						
				
		
		
				
						
      
				为了完成这个任务,我们就需要使用
				
						commons.collections.comparators 
						
						
提供的几个装饰类,ReverseComparator,NullComparator,
FixedOrderComparator或者ComparatorUtils这个实用类。
		
		
				
						
						
    
				下边分别说明反序排列,允许空值排列和自定义顺序排列的实现方法。 
		
		
				
						
    
				当我们想对让一个比较器按着反序进行排列的时候,可以使用如下的形
式: 
		
		
				
						
      comparator = new ReverseComparator(comparator);
		
		
				
						
      
				需要说明的是:这个功能的实现可以在排完序后对要排序的
				array 
				或者
				
						
						
list 
				调用其
				reverse 
				()方法即可。但是这种做法并不适合下边谈到的对
				
						
						
bean 
				的多字段排序时,而只对某一个字段逆序的情况。 
     当对一个比较器进行特定顺序排列时需要用到FixedOrderComparator 。
这个类用于定义一个特殊的顺序,对一组对象按照这样的自定义顺序进行排序。
具体的事例如下:
		
				String[] severityOrder = { "Critical", "Minor", "Enhancement" }; 
		
		
				Comparator severityComparator = new FixedOrderComparator
				   (severityOrder);
		
		
				Comparator comparator=new BeanComparator("title",severityComparator) 
				;
				
						
								
								
						
				
		
		
				如上的程序便可以对
				
				
				bean 
				的
				
				
				title 
				属性按着数组中特定
				
						
						
				
		
		
				的顺序进行排序!
				
						
								
								
						
				
		
		
				最后需要说明的是,以上谈到的几个装饰在
				
				
				ComparatorUtils 
				这个实用类中也提供了支持。
				
				
				
						
						
				
		
		
				具体使用如下:
				
				
				
						
						
				
		
		
				按着
				
				
				bean 
				的属性为
				
				
				null 
				时进行排序,可以选择属性为
				
				
				null 
				时排在前边还是后边!
				
				
				
						
						
				
		
		
				ComparatorUtils.nullLowComparator(comparator);  
				或者
				
						ComparatorUtils.nullHighComparator(comparator); 
				
		
		
				当对一个排序器逆序时:
				
						
								
								
						
				
		
		
				ComparatorUtils.reversedComparator(mycmp); // 
				逆序
				
						
								
								
						
				
		
		
				
						 
				
		
		
				
						多个属性的排序
				
				
						
						
				
				
						
								
								
						
				
		
		
				当我们想对
				
				
				bean 
				的多个属性进行排序的时候,需要用到
				
				
				commons.collections. ComparatorChain 
				。这个类
				
				
				定义一组Comparator链,链中的Comparator对象会被依次执行。我们可以通过该类的 addComparator() 
				方法进行将当个的
				
				
				comparator 
				对象加入到
				
				
				comparator 
				链中,当使用的时候就可以和使用单个
				
				
				comparator 
				一样。因为
				
				
				comparatorChain 
				也继承了
				
				
				comparator 
				的借口。当我们添加单个的
				
				
				comparator 
				的时候,就可以利用上边谈到的对
				
				
				comparator 
				进行装饰。
				
				
				
						
						
				
		
		
				ComparatorChain comparatorChain = new ComparatorChain( ); 
		
		
				comparatorChain.addComparator( new BeanComparator( "name" ) ); 
		
		
				comparatorChain.addComparator( new BeanComparator( "author" ) ); 
		
		
				comparaterChain.addComparator( new ReverseComparator                              
				                         
				
						(new BeanComparator("author") ); 
				
		
		
				    
				
						 
				
				具体使用的时候如下:
				
				
				
						
						
				
		
		
				    Arrays.sort( books, comparatorChain ); 
		
		
				 
				
				
				这个样子就可以将这个
				
				
				comparator 
				传给
				
				
				sort 
				()方法。当谈到对
				
				
				bean 
				的多字段排序,而只对某一个字段逆序的情况时,可以参考如下的实现。
				
				
				
						
						
				
		
		
				     
				
						 ComparatorChain comparatorChain = new ComparatorChain( ); 
		
		
				     comparatorChain.addComparator( new BeanComparator( "name" ) );
				
						
						
				
		
		
				      
				
						 
				
				这样子就可以实现了对
				
				
				bean 
				的
				
				
				name 
				按着正序排列而对
				
				
				author 
				属性按着逆序排列。
				
				
				
						
						
				
		
		
				
						对组合
				
				
						
						
				
				
						bean 
				
				
						进行排序
				
				
						
						
				
				
						
								
								
						
				
		
		
				     
				
						 
				
				当一个
				
				
				bean 
				的某个属性是另外一个
				
				
				java bean 
				的时候,而我们有想按着那个被组合进来
				
				
				bean 
				的某个属性进行排序的时候,我们只需要很简单的将
				
				
				BeanComparator 
				的参数设定成
				
				
				bean.property 
				的形式,比如想对按着
				
				
				book 
				的
				
				
				author 
				中的
				
				
				title 
				属性进行排序的时候就可以参考以下的形式:
				
				
				
						
						
				
		
		
				new BeanComparator
				
				
				
						
						
				
		
		
				("author.title",severityComparator))
				
				
				
						
						
				
		
		
				Comparable 
				接口的实现
				
				
				
						
						
				
		
		
				     
				
						 
				
				最后如果想对
				
				
				author 
				类实现
				
				
				Comparable 
				接口可以参考如下的实现:
				
				
				
						
						
				
		
		
				public class Book implements Comparable { 
		
		
				public int compareTo(Object arg0) { 
		
		
				// comparators setup 
		
		
				String[] severityOrder = { "Critical", "Major", "Minor", "Enhancement" }; 
		
		
				// 
				用于定义一个特殊的顺序,对一组对象按照这样的自定义顺序进行排序;
				
						
								
								
						
				
		
		
				Comparator severityComparator = new FixedOrderComparator(severityOrder); 
		
		
				ComparatorChain compChain = new ComparatorChain(); 
		
		
				
						       // 
				通过为属性指定一个已经存在的
				
						Comparator 
				
				,而非采用默认的自然顺序
				
						
								
								
						
				
		
		
				compChain.addComparator(new BeanComparator("author. 
		
		
				title", severityComparator)); 
		
		
				
						    
						 compChain.addComparator(new NullComparator 
		
		
				(new BeanComparator("name"), true)); 
		
		
				compChain .addComparator(new ReverseComparator 
		
		
				(new BeanComparator("id"))); 
		
		
				
						    
						 return compChain.compare(this, arg0); 
		
		
				
						    } 
		
		
				} 
		
		
				  
				
				
				另外一个实现思路是:利用
				
				
				commons.lang.compareBulder 
				实现。但是却失去了以上的装饰功能!
				
						
						
				
		
		
				
						 
				
		
		 
		
				
						   
				
				最后需要说明的是,由于我在工作中最近用到这些排序,所以整理了一下,希望对您有用。同时参考了很多网上的资料,谢!
  
		
		
				
						  事例代码我放到了:
				
				
						
								commons2006@126.com
						
						,
				
				
						密码是
						
								commons2006
						
				
		
		
				
						 
				
		
		 
	posted on 2006-09-16 16:33 
张氏兄弟 阅读(1170) 
评论(1)  编辑  收藏