自定义实体类支持多字段排序的排序器

前言

对于基本类型的集合排序,可以直接借助java提供的排序器进行比较排序,而对于集合中的实体类,想要实现排序需要自定义排序器,常见的有两种方式:
一、实体类实现Comparator接口的compare方法进行排序
二、将比较器抽离出来,生成一个通用的比较器(比较常用)


记录一下第二种的用法

构建一个反射工具,用于根据传入的字段名的字符串解析出想要进行的排序的字段
public class ReflexUtil {
    static Logger logger = LoggerFactory.getLogger(ReflexUtil.class);

    //getMethod
    static public Object invokeMethod(String propertiesName, Object object) {
        try {
            if(object==null) return null;
            //如果传入的字段名不包含. 说明是一个单纯的字段,直接返回get方法执行的结果
            if (!propertiesName.contains(".")) {
                String methodName = "get"+getMethodName(propertiesName);
                Method method = object.getClass().getMethod(methodName);
                return method.invoke(object);
            }
            //如果是带有.的字符串,需要先获取真实的字段值,即.后面的值
            String methodName = "get"+getMethodName(propertiesName.substring(0,propertiesName.indexOf(".")));
            Method method = object.getClass().getMethod(methodName);
            return invokeMethod(propertiesName.substring(propertiesName.indexOf(".")+1), method.invoke(object));

        } catch (Exception e) {
            logger.error(e.toString(), e);
            return null;
        }
    }

    //将首字母大写
    private static String getMethodName(String fildeName) {
        byte[] items = fildeName.getBytes();
        items[0] = (byte) ((char) items[0] - 'a' + 'A');
        return new String(items);
    }
}
然后编写一个通用的排序比较器,实现排序逻辑
public class CompareUtil {
    //sort 1正序 -1 倒序  filed 多字段排序
    public static <T> Comparator createComparator(int sort, String... filed) {
        return new ImComparator(sort, filed);
    }

    public static class ImComparator implements Comparator {
        int sort = 1;
        String[] filed;

        public ImComparator(int sort, String... filed) {
            this.sort = sort == -1 ? -1 : 1;
            this.filed = filed;
        }

        @Override
        public int compare(Object o1, Object o2) {
            int result = 0;
            for (String file : filed) {
                Object value1 = ReflexUtil.invokeMethod(file, o1);
                Object value2 = ReflexUtil.invokeMethod(file, o2);
                if (value1 == null || value2 == null) {
                    continue;
                }
                if (value1 instanceof Integer) { //Integer整数序排序
                    int v1 = Integer.valueOf(value1.toString());
                    int v2 = Integer.valueOf(value2.toString());
                    if (v1 == v2) continue;
                    //正序排序
                    if (sort == 1) {
                        return v1 - v2;
                    } else if (sort == -1) {
                        return v2 - v1;
                    }
                } else if (value1 instanceof Date) {  //Date类型排序
                    Date d1 = (Date) value1;
                    Date d2 = (Date) value2;
                    if (d1.compareTo(d2) == 0) continue;
                    if (sort == 1) {
                        return d1.compareTo(d2);
                    } else if (sort == -1) {
                        return d2.compareTo(d1);
                    }
                } else if (value1 instanceof Long) { //Long排序
                    long v1 = Long.valueOf(value1.toString());
                    long v2 = Long.valueOf(value2.toString());
                    if (v1 == v2) continue;
                    if (sort == 1) {
                        return v1 > v2 ? 1 : -1;
                    } else if (sort == -1) {
                        return v2 > v1 ? 1 : -1;
                    }
                } else if (value1 instanceof Double) { //Double排序
                    Double v1 = Double.valueOf(value1.toString());
                    Double v2 = Double.valueOf(value2.toString());
                    if (v1 == v2) continue;
                    if (sort == 1) {
                        return v1 > v2 ? 1 : -1;
                    } else if (sort == -1) {
                        return v2 > v1 ? 1 : -1;
                    }
                }

            }

            return result;
        }
    }
}
测试
@Data
@ToString
public class Hand {
    private Integer length;
    private String  desc;

    public Hand(Integer length, String desc) {
        this.length = length;
        this.desc = desc;
    }
}
@Data
@ToString
public class Person {
    private String name;
    private Integer age;
    private Date birth;

    private Hand hand;

    public Person(String name, Integer age, Date birth, Hand hand) {
        this.name = name;
        this.age = age;
        this.birth = birth;
        this.hand = hand;
    }
}
public class SortTest {
    public static void main(String[] args) throws ParseException {
        Hand hand1 = new Hand(10,"左手");
        Hand hand2 = new Hand(12,"右手");
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = dateFormat.parse("2018-10-01");
        Calendar calendar = new GregorianCalendar(2014,10,1);
        Date date1 = calendar.getTime();
        Person p1 = new Person("小红",10,date,hand1);
        Person p2 = new Person("小吕",6,date1,hand2);
        List<Person> list = new ArrayList<>();
        list.add(p1);
        list.add(p2);
        System.out.println(list);
        Collections.sort(list,CompareUtil.createComparator(-1,"hand.length"));
        System.out.println(list);
        Collections.sort(list,CompareUtil.createComparator(-1,"age"));
        System.out.println(list);
        Collections.sort(list,CompareUtil.createComparator(1,"birth"));
        System.out.println(list);
    }
}
结果
[Person(name=小红, age=10, birth=Mon Oct 01 00:00:00 CST 2018, hand=Hand(length=10, desc=左手)), Person(name=小吕, age=6, birth=Sat Nov 01 00:00:00 CST 2014, hand=Hand(length=12, desc=右手))]
[Person(name=小吕, age=6, birth=Sat Nov 01 00:00:00 CST 2014, hand=Hand(length=12, desc=右手)), Person(name=小红, age=10, birth=Mon Oct 01 00:00:00 CST 2018, hand=Hand(length=10, desc=左手))]
[Person(name=小红, age=10, birth=Mon Oct 01 00:00:00 CST 2018, hand=Hand(length=10, desc=左手)), Person(name=小吕, age=6, birth=Sat Nov 01 00:00:00 CST 2014, hand=Hand(length=12, desc=右手))]
[Person(name=小吕, age=6, birth=Sat Nov 01 00:00:00 CST 2014, hand=Hand(length=12, desc=右手)), Person(name=小红, age=10, birth=Mon Oct 01 00:00:00 CST 2018, hand=Hand(length=10, desc=左手))]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值