寫了一個比較器,實現功能如下:
有列表List list,list存放對象(如Person p等),對象里面有若干屬性。
要求對列表按照列表對象的某個屬性進行排序。列表對象類型未知,對象屬性未知。
通過通知比較器列表對象類型和排序字段,以及升序或降序,來對列表進行排序
(其實就是實現復雜對象列表排序)
注:由于實際應用中,要排序的列表結果集已經得到,程序應用沒有錯誤或異常,
比較器只實現排序功能,因此在比較器中封閉異常
本人實現代碼如下,希望大家提供一些意見來完善
//比較器總接口類
package myutil.comparator;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Comparator;
public abstract class ListComparator implements Comparator{
public static final int DATATYPE_STRING=1;//字符串類型
public static final int DATATYPE_DOUBLE=2;//雙精度浮點型
public static final int DATATYPE_DATE=3;//日期類型
public static final int ORDER_ASC=100;//順序
public static final int ORDER_DESC=101;//倒序
protected String colName="";//被比較的屬性名稱
protected Class cl=null;//被比較的列表對象的類型
protected int order=ORDER_ASC;//順序或倒序,默認為順序
/**
* 比較器的比較方法,在子類中實現
*/
public abstract int compare(Object o1, Object o2);
/**
* 獲取兩個比較對象的指定屬性(colName)的值
* @param obj1 要比較的一個對象
* @param obj2 要比較的另一個對象
* @return Object[],被比較的兩個對象中指定屬性的值的數組
*/
protected Object[] getValueObj(Object obj1,Object obj2){
if(obj1==null || obj2==null)
return null;
try {
int first=colName.charAt(0)-32;//獲得字段名的首字母,并轉化成大寫
String mName="get"+(char)first+colName.substring(1);//獲得字段的獲取方法
Method m = cl.getMethod(mName,null);//構造方法對象
Object val1=m.invoke(obj1,null);//調用方法,得到對象1的colName屬性值
Object val2=m.invoke(obj2,null);//調用方法,得到對象2的colName屬性值
return new Object[]{val1,val2};//返回對象數組
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
/**
* 交換兩個對象,用于控制升序或降序
* @param obj1
* @param obj2
* @return
*/
protected Object[] swap(Object obj1,Object obj2){
if(this.order==ORDER_DESC){
Object oTmp=obj1;
obj1=obj2;
obj2=oTmp;
}
return new Object[]{obj1,obj2};
}
/**
* @return 排序方式(順序/倒序)
*/
public final int getOrder() {
return order;
}
/**
* @param 排序方式(順序/倒序)
*/
public final void setOrder(int order) {
this.order = order;
}
/**
* @return 列表包裝類型
*/
public final Class getCl() {
return cl;
}
/**
* @param 列表包裝類型
*/
public final void setCl(Class cl) {
this.cl = cl;
}
/**
* @return 排序字段
*/
public final String getColName() {
return colName;
}
/**
* @param 排序字段
*/
public final void setColName(String colName) {
this.colName = colName;
}
public String toString(){
StringBuffer buf=new StringBuffer();
buf.append("Column Name(colName):").append(this.colName).append(";");
buf.append("Class In List Name(c1):").append(cl.getName()).append(";");
buf.append("Order Type(order):").append(this.order).append(".");
return buf.toString();
}
}
//工廠類
package myutil.comparator;
public class ListComparatorFactory {
public static final ListComparator getListComparator(int dataType){
switch(dataType){
case ListComparator.DATATYPE_STRING:
return new StringListComparator();
case ListComparator.DATATYPE_DOUBLE:
return new NumberListComparator();
case ListComparator.DATATYPE_DATE:
return new DateListComparator();
default:
return new DefaultListComparator();
}
}
}
//默認實現類
package myutil.comparator;
public class DefaultListComparator extends ListComparator{
public int compare(Object obj1, Object obj2) {
Object swapObj[]=this.swap(obj1,obj2);
Object obj[]=this.getValueObj(swapObj[0],swapObj[1]);
if(obj==null)
return 0;
Comparable cmp1=(Comparable)obj[0];
Comparable cmp2=(Comparable)obj[1];
return cmp1.compareTo(cmp2);
}
public String toString(){
return super.toString();
}
}
//比較字段為日期型的實現類
package myutil.comparator;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateListComparator extends ListComparator{
public int compare(Object obj1, Object obj2) {
Object swapObj[]=this.swap(obj1,obj2);
Object obj[]=this.getValueObj(swapObj[0],swapObj[1]);
if(obj==null)
return 0;
DateFormat format=new SimpleDateFormat("yyyyMMddhhmmss");
Comparable cmp1,cmp2;
try{
cmp1=format.parse(obj[0]==null?"00000000000000":obj[0].toString());
}catch(ParseException pe){
cmp1=new Date(0);
}
try {
cmp2=format.parse(obj[1]==null?"00000000000000":obj[1].toString());
} catch (ParseException e) {
cmp2=new Date(0);
}
return cmp1.compareTo(cmp2);
}
public String toString(){
return super.toString();
}
}
//比較字段為數字型的實現類,兼容整數,浮點數
package myutil.comparator;
public class NumberListComparator extends ListComparator{
public int compare(Object obj1, Object obj2) {
Object swapObj[]=this.swap(obj1,obj2);
Object obj[]=this.getValueObj(swapObj[0],swapObj[1]);
if(obj==null)
return 0;
Comparable cmp1,cmp2;
try{
cmp1=new Double(obj[0]==null?"0":obj[0].toString());
}catch(NumberFormatException nfe){
cmp1=new Double(0);
}
try{
cmp2=new Double(obj[1]==null?"0":obj[1].toString());
}catch(NumberFormatException nfe){
cmp2=new Double(0);
}
return cmp1.compareTo(cmp2);
}
public String toString(){
return super.toString();
}
}
//比較字段為字符串型的實現類
package myutil.comparator;
public class StringListComparator extends ListComparator{
public int compare(Object obj1, Object obj2) {
Object swapObj[]=this.swap(obj1,obj2);
Object obj[]=this.getValueObj(swapObj[0],swapObj[1]);
if(obj==null)
return 0;
Comparable cmp1=obj[0]==null?"":obj[0].toString();
Comparable cmp2=obj[1]==null?"":obj[1].toString();
return cmp1.compareTo(cmp2);
}
public String toString(){
return super.toString();
}
}
//應用測試示例
package myutil.comparator.test;
public class MyFile {
private int age;
/**
* @return the age
*/
public final int getAge() {
return age;
}
/**
* @param age the age to set
*/
public final void setAge(int age) {
this.age = age;
}
public void display() {
// TODO Auto-generated method stub
}
public String toString(){
return String.valueOf(age);
}
}
package myutil.comparator.test;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import myutil.comparator.ListComparator;
import myutil.comparator.ListComparatorFactory;
public class SortTest {
public List doIt(){
List list=new ArrayList(10);
Random ran=new Random();
for(int i=0;i<10;i++){
MyFile mf=new MyFile();
mf.setAge(ran.nextInt(100));
list.add(mf);
}
return list;
}
/**
* @param args
*/
public static void main(String[] args) {
SortTest t=new SortTest();
List list=t.doIt();
ListComparator cm=ListComparatorFactory.getListComparator(ListComparator.DATATYPE_DOUBLE);
cm.setColName("age");
cm.setCl(MyFile.class);
System.out.println(cm);
cm.setOrder(ListComparator.ORDER_DESC);
Collections.sort(list,cm);
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
}
}