List里的元素为对象,按照对象的多个属性升降排序

  1  package com.zte.crm.equipmentconfigure.su.utils;
  2 
  3 import java.lang.reflect.Field;
  4 import java.text.NumberFormat;
  5 import java.util.*;
  6 
  7  /**
  8   * 集合工具类
  9   * @author 6092002913
 10   * @date 2019-05-21
 11   */
 12 public class ListUtil {
 13     private ListUtil() {}
 14 
 15     /**
 16      * 给list的每个属性都指定是升序还是降序
 17      * list元素的属性可以是数字(byte、short、int、long、float、double等,支持正数、负数、0)、char、
 18      * String、java.util.Date
 19      * @param list
 20      * @param sortNameArr  排序参数数组
 21      * @param typeArr      每个属性对应的升降序数组, true升序,false降序
 22      */
 23 
 24     public static <E> void sort(List<E> list, final String[] sortNameArr, final boolean[] typeArr) {
 25         if (sortNameArr.length != typeArr.length) {
 26             throw new RuntimeException("属性数组元素个数和升降序数组元素个数不相等");
 27         }
 28         list.sort((a, b) -> {
 29             int ret = 0;
 30             try {
 31                 for (int i = 0; i < sortNameArr.length; i++) {
 32                     ret = ListUtil.compareObject(sortNameArr[i], typeArr[i], a, b);
 33                     if (0 != ret) {
 34                         break;
 35                     }
 36                 }
 37             } catch (Exception e) {
 38                 e.printStackTrace();
 39             }
 40             return ret;
 41         });
 42     }
 43 
 44      /** 对2个对象按照指定属性名称进行排序
 45      * @param sortname 属性名称
 46      * @param isAsc true升序,false降序
 47      *
 48      * @param a
 49      * @param b
 50      * @return
 51       * @throws Exception
 52      */
 53     private static <E> int compareObject(final String sortname, final boolean isAsc, E a, E b) throws Exception {
 54         int ret;
 55         Object value1 = ListUtil.forceGetFieldValue(a, sortname);
 56         Object value2 = ListUtil.forceGetFieldValue(b, sortname);
 57         String str1 = value1.toString();
 58         String str2 = value2.toString();
 59         if (value1 instanceof Number && value2 instanceof Number) {
 60             int maxlen = Math.max(str1.length(), str2.length());
 61             str1 = ListUtil.addZero2Str((Number) value1, maxlen);
 62             str2 = ListUtil.addZero2Str((Number) value2, maxlen);
 63         } else if (value1 instanceof Date && value2 instanceof Date) {
 64             long time1 = ((Date) value1).getTime();
 65             long time2 = ((Date) value2).getTime();
 66             int maxlen = Long.toString(Math.max(time1, time2)).length();
 67             str1 = ListUtil.addZero2Str(time1, maxlen);
 68             str2 = ListUtil.addZero2Str(time2, maxlen);
 69         }
 70         if (isAsc) {
 71             ret = str1.compareTo(str2);
 72         } else {
 73             ret = str2.compareTo(str1);
 74         }
 75         return ret;
 76     }
 77 
 78     /**
 79      * 给数字对象按照指定长度在左侧补0.
 80      * 使用案例: addZero2Str(11,4) 返回 "0011", addZero2Str(-18,6)返回 "-000018"
 81      * @param numObj 数字对象
 82      * @param length 指定的长度
 83      * @return
 84      */
 85     private static String addZero2Str(Number numObj, int length) {
 86         NumberFormat nf = NumberFormat.getInstance();
 87         // 设置是否使用分组
 88         nf.setGroupingUsed(false);
 89         // 设置最大整数位数
 90         nf.setMaximumIntegerDigits(length);
 91         // 设置最小整数位数
 92         nf.setMinimumIntegerDigits(length);
 93         return nf.format(numObj);
 94     }
 95 
 96     /**
 97      * 获取指定对象的指定属性值(去除private,protected的限制)
 98      *
 99      * @param obj 属性名称所在的对象
100      * @param fieldName 属性名称
101      * @return
102      * @throws Exception
103      */
104     private static Object forceGetFieldValue(Object obj, String fieldName) throws Exception {
105         Field field = obj.getClass().getDeclaredField(fieldName);
106         Object object = null;
107         boolean accessible = field.isAccessible();
108         if (!accessible) {
109             // 如果是private,protected修饰的属性,需要修改为可以访问的
110             field.setAccessible(true);
111             object = field.get(obj);
112             // 还原private,protected属性的访问性质
113             field.setAccessible(accessible);
114             return object;
115         }
116         object = field.get(obj);
117         return object;
118     }
119 }

 

posted on 2019-07-13 15:52  Luwak  阅读(265)  评论(0)    收藏  举报

导航