包装类排序、list集合排序

需求:由于某方便的需求,需要根据对象的属性排序,就从网上找了好多资料、整理、封装,可以实现对象属性的排序,对象的属性类型可以是字符串、整形、时间类型、包装类;直接上代码,代码中都有信息的注释,不再赘述。

1.主要的实现类SortListObjectAttr

package com.anzhonghui.zawsze.pojo;
import java.lang.reflect.Method;
import java.sql.Timestamp;
import java.util.Comparator;
import java.util.Date;
import com.anzhonghui.zawsze.util.CommonUtil;
/**
*
* @ClassName: SortListObjectAttr.java
* @Description: 根据指定的属性名排序包装类集合
*
* @version: v1.0.0
* @author: 安仲辉
* @date: 2018年5月5日 下午9:02:13
*
* Modification History:
* Date         Author          Version            Description
*---------------------------------------------------------*
* 2018年5月5日         安仲辉            v1.0.0                                           修改原因
*/
public class SortListObjectAttr<T> implements Comparator<T> {
    //1.属性名称
    private String  propertyName;  
    //2.是否升序
    private boolean isAsc;  
    //3.是否是包装类的属性
    private Boolean isObjectAttr;
  
    //用于包装类普通字段的比较
    public SortListObjectAttr(String propertyname, boolean isasc) {  
        this.propertyName = propertyname;  
        this.isAsc = isasc;
    }  
    
    //用于包装类中含包装类的比较
    public SortListObjectAttr(String propertyname, boolean isasc, Boolean isObjectAttr) {  
        this.propertyName = propertyname;  
        this.isAsc = isasc;
        this.isObjectAttr = isObjectAttr;
    }  
  
    /**
     *
     * @Function: SortListObjectAttr.java
     * @Description: 重写的排序方法
     *
     * @param:比较的对象
     * @return:返回比较大小的结果
     *
     * @version: v1.0.0
     * @author: 安仲辉
     * @date: 2018年5月5日 下午9:00:38
     *
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })  
    @Override  
    public int compare(T b1, T b2) {
        Class<?> clz = b1.getClass();//获取对象的类
        Object o1 = null;
        Object o2 = null;
        Method mth = null;
        if(isObjectAttr == null){
            mth = getPropertyMethod(clz, propertyName);//根据类和属性名,获取完整的get方法
            try {
                o1 = mth.invoke(b1);//根据定方法名获取的值(从对象中获取要排序属性的值)
                o2 = mth.invoke(b2);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            if (!isObjectAttr) {
                mth = getPropertyMethod(clz, propertyName);
                try {
                    o1 = mth.invoke(b1);
                    o2 = mth.invoke(b2);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {
                //类中包装类操作
                try {
                    String[] split = propertyName.split("[.]");
                    Method mthTemp = getPropertyMethod(clz, split[0]);
                    Class<?> clz2 = mthTemp.getReturnType();//获取类中的包装类类型
                    mth = getPropertyMethod(clz2, split[1]);//获取包装类中指定的属性
                
                    if(mthTemp.invoke(b1) != null){
                        o1 = mth.invoke(mthTemp.invoke(b1));//先从排序类中获取包装类,再从包装类中获取值
                    }
                    if(mthTemp.invoke(b2) != null){
                        o2 = mth.invoke(mthTemp.invoke(b2));
                    }
                } catch (ArrayIndexOutOfBoundsException arrayIndexOutOfBoundsException) {
                    System.out.println("请检查参数:方法名、是否是包装类的方法 是否正确");
                    arrayIndexOutOfBoundsException.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        
        if (o1 == null && o2 == null)
            return 0;
        if (o1 == null && o2 != null) {//如果是空值,根据类型获取默认值,避免因null影响排序
            o1 = getDefaultValue(mth.getReturnType());
        } else if (o1 != null && o2 == null) {
            o2 = getDefaultValue(mth.getReturnType());
        }
        
        Comparable value1 = (Comparable) o1;
        Comparable value2 = (Comparable) o2;
        if (isAsc) {//升序
            return value1.compareTo(value2);
        } else {
            return value2.compareTo(value1);
        }
    }
    
  
    /**
     *   
     * @Function: SortList.java
     * @Description: 获取方法
     *
     * @param: clz 查询的类; propertyName 查询的属性名
     * @return: 根据属性名从类中查询到的get方法  example:getAge
     *
     * @version: v1.0.0
     * @author: 安仲辉
     * @date: 2018年5月5日 下午6:25:29
     *
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })  
    public static Method getPropertyMethod(Class clz, String propertyName) {  
        Method mth = null;  
        try {  
            mth = clz.getMethod("get" + CommonUtil.upperCase(propertyName));  
        } catch (Exception e) {  
            System.out.println("获取方法发生错误!");  
            e.printStackTrace();
        }  
        return mth;  
    }  
    
    /**
     *
     * @Function: SortList.java
     * @Description: 根据类型获取默认值(为了方便空值的排序)
     *
     * @param: 类型
     * @return:返回默认值
     *
     * @version: v1.0.0
     * @author: 安仲辉
     * @date: 2018年5月5日 下午6:31:07
     *
     */
    public static Object getDefaultValue(Class<?> type){
        if (type == String.class) {
            return "";
        } else if (type == Integer.class) {
            return 0;
        } else if (type == Date.class){
            return new Date(0);
        } else if (type == Timestamp.class) {
            return new Timestamp(0);
        }
        return null;
    }
  
    public String getPropertyName() {  
        return propertyName;  
    }  
  
    public void setPropertyName(String propertyName) {  
        this.propertyName = propertyName;  
    }  
  
    public boolean isAsc() {  
        return isAsc;  
    }  
  
    public void setAsc(boolean isAsc) {  
        this.isAsc = isAsc;  
    }
    public boolean isObjectAttr() {
        return isObjectAttr;
    }
    public void setObjectAttr(boolean isObjectAttr) {
        this.isObjectAttr = isObjectAttr;
    }  
}


2.工具类,CommonUtil

package  com . anzhonghui . zawsze . util ;
/**
 *
 *  @ClassName : CommonUtil.java
 *  @Description : 一些常用的工具类方法
 *
 *  @version : v1.0.0
 *  @author : AN
 *  @date : 2018年5月5日 下午9:06:46
 *
 * Modification History:
 * Date         Author          Version            Description
 * --------------------------------------------------------- *
 * 2018年5月5日            安仲辉                     v1.0.0                                         修改原因
 */
public   class   CommonUtil   {    
     /**
     *
     *  @Function : SortList.java
     *  @Description : 首字母大写
     *
     *  @param :需要首字母大写的字符串
     *  @return :首字母大写后的字符串
     *
     *  @version : v1.0.0
     *  @author : 安仲辉
     *  @date : 2018年5月5日 下午6:24:09
     *
     */
     public   static   String   upperCase( String   str )   {  
         char []   ch   =   str . toCharArray () ;  
         if   ( ch [ 0 ]   >=   'a'   &&   ch [ 0 ]   <=   'z' )   {  
             ch [ 0 ]   =   ( char )   ( ch [ 0 ]   -   32 ) ;  
         }  
         return   new   String ( ch ) ;  
     }
}

3.MyTest测试类、User测试排序的类,Father是User的某个属性类

## 测试
package  com . anzhonghui . zawsze . test ;
import  java . sql . Timestamp ;
import  java . util . ArrayList ;
import  java . util . Collections ;
import  java . util . List ;
import  org . junit . Test ;
import  com . anzhonghui . zawsze . pojo . SortListObjectAttr ;
public   class   MyTest   {
      @Test
      public   void   fun1(){
            //1.根据用户的用户名,降序排序
            List < User >   lists   =   new   ArrayList <> () ;
           
            User   user   =   new   User ( "an" ,   10 ,   new   Timestamp ( System . currentTimeMillis ())) ;
            User   user2   =   new   User ( "cc" ,   null ,   new   Timestamp ( System . currentTimeMillis () - 1000 * 60 * 60 )) ;
            User   user3   =   new   User ( "bb" ,   12 ,   null ) ;
            User   user4   =   new   User ( null ,   15 ,   new   Timestamp ( System . currentTimeMillis () - 1000 * 60 * 60 * 2 )) ;
           
            lists . add ( user ) ;
            lists . add ( user2 ) ;
            lists . add ( user3 ) ;
            lists . add ( user4 ) ;
           
            System . out . println ( "排序前的内容:" ) ;
            for   ( User   us   :   lists )   {
                 System . out . println ( us . toString ()) ;
            }
           
            Collections . sort ( lists ,   new   SortListObjectAttr < User > ( "name" ,   false )) ;
           
            System . out . println ( "排序后的内容:" ) ;
            for   ( User   us   :   lists )   {
                 System . out . println ( us . toString ()) ;
            }
           
            //根据用户对象的father属性的name属性排序
            List < User >   lists2   =   new   ArrayList <> () ;
            User   user5   =   new   User ( "an" ,   10 ,   new   Timestamp ( System . currentTimeMillis ()) , new   Father ( "33" )) ;
            User   user6   =   new   User ( "bb" ,   null ,   new   Timestamp ( System . currentTimeMillis () - 1000 * 60 * 60 )) ;
            User   user7   =   new   User ( "cc" ,   12 ,   null , new   Father ( "22" )) ;
            User   user8   =   new   User ( null ,   15 ,   new   Timestamp ( System . currentTimeMillis () - 1000 * 60 * 60 * 2 ) , new   Father ( "11" )) ;
            lists2 . add ( user5 ) ;
            lists2 . add ( user6 ) ;
            lists2 . add ( user7 ) ;
            lists2 . add ( user8 ) ;
           
            System . out . println ( "包装类的排序前的内容:" ) ;
            for   ( User   us   :   lists2 )   {
                 System . out . println ( us . toString ()) ;
            }
           
            Collections . sort ( lists2 ,   new   SortListObjectAttr < User > ( "father.name" ,   true ,   true )) ;
           
            System . out . println ( "包装类的排序后的内容:" ) ;
            for   ( User   us   :   lists2 )   {
                 System . out . println ( us . toString ()) ;
            }
      }            
}

## 测试
package  com . anzhonghui . zawsze . test ;
import  java . sql . Timestamp ;
public   class   User   {
      private   String   name ;
      private   Integer   age ;
      private   Timestamp   birth ;
      private   Father   father ;
     
      public   User( String   name ,   Integer   age ,   Timestamp   birth )   {
            super () ;
            this . name   =   name ;
            this . age   =   age ;
            this . birth   =   birth ;
      }
     
      public   User( String   name ,   Integer   age ,   Timestamp   birth ,   Father   father )   {
            super () ;
            this . name   =   name ;
            this . age   =   age ;
            this . birth   =   birth ;
            this . father   =   father ;
      }
      public   String   getName()   {
            return   name ;
      }
      public   void   setName( String   name )   {
            this . name   =   name ;
      }
      public   Integer   getAge()   {
            return   age ;
      }
      public   void   setAge( Integer   age )   {
            this . age   =   age ;
      }
      public   Timestamp   getBirth()   {
            return   birth ;
      }
      public   void   setBirth( Timestamp   birth )   {
            this . birth   =   birth ;
      }
      public   Father   getFather()   {
            return   father ;
      }
      public   void   setFather( Father   father )   {
            this . father   =   father ;
      }
      @Override
      public   String   toString()   {
            return   "User [name="   +   name   +   ", age="   +   age   +   ", birth="   +   birth   +   ", father="   +   father   +   "]" ;
      }   
}
 
## 测试
package  com . anzhonghui . zawsze . test ;
public   class   Father   {
      private   String   name ;
     
      public   String   getName()   {
            return   name ;
      }
      public   void   setName( String   name )   {
            this . name   =   name ;
      }
      public   Father ( String   name )   {
            super () ;
            this . name   =   name ;
      }
      @Override
      public   String   toString()   {
            return   "Father [name="   +   name   +   "]" ;
      }
     
}

4.测试结果

排序前的内容:对User的name属性进行降序排序
User [name=an, age=10, birth=2018-05-09 11:31:21.309, father=null]
User [name=cc, age=null, birth=2018-05-09 10:31:21.309, father=null]
User [name=bb, age=12, birth=null, father=null]
User [name=null, age=15, birth=2018-05-09 09:31:21.309, father=null]
排序后的内容:
User [name=cc, age=null, birth=2018-05-09 10:31:21.309, father=null]
User [name=bb, age=12, birth=null, father=null]
User [name=an, age=10, birth=2018-05-09 11:31:21.309, father=null]
User [name=null, age=15, birth=2018-05-09 09:31:21.309, father=null]

包装类的排序前的内容:对father属性的name属性进行升序排序 
User [name=an, age=10, birth=2018-05-09 11:31:21.322, father=Father [name=33]]
User [name=bb, age=null, birth=2018-05-09 10:31:21.322, father=null]
User [name=cc, age=12, birth=null, father=Father [name=22]]
User [name=null, age=15, birth=2018-05-09 09:31:21.322, father=Father [name=11]]
包装类的排序后的内容:
User [name=bb, age=null, birth=2018-05-09 10:31:21.322, father=null]
User [name=null, age=15, birth=2018-05-09 09:31:21.322, father=Father [name=11]]
User [name=cc, age=12, birth=null, father=Father [name=22]]
User [name=an, age=10, birth=2018-05-09 11:31:21.322, father=Father [name=33]]

5.可以直接用这个jar包

https://download.csdn.net/download/qq_35398517/10402728

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值