失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 结合自定义注解 java反射和comparator实现对象的排序

结合自定义注解 java反射和comparator实现对象的排序

时间:2020-09-04 06:53:47

相关推荐

结合自定义注解 java反射和comparator实现对象的排序

开头一注:本代码是在学习comparator时,想到是否能写一个排序的工具类,在思考过后决定结合注解来实现排序,目前代码还比较粗犷,请大神指教,请大家轻喷。

一、新增自定义注解

@Documented@Target({ElementType.FIELD, ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)public @interface MySort {int value() default 0;}

注解小释:

@Documented注解,是被用来指定自定义注解是否能随着被定义的java文件生成到JavaDoc文档当中。

@Retention注解,翻译为持久力、保持力。即用来修饰自定义注解的生命力。

RetentionPolicy.RUNTIME,表示这个注解可以在运行期的加载阶段被加载到Class对象中。所以在程序运行阶段,可以通过反射得到这个注解,并通过判断是否有这个注解或这个注解中属性的值,从而执行不同的程序代码段。

@Target注解,是专门用来限定某个自定义注解能够被应用在哪些Java元素上面的。

ElementType.FIELD 表示本注解可以作用在属性上。

ElementType.METHOD 表示可以注解到方法上。期待的是可以兼容方法排序,目前本文章还未实现。

value 表示的是排序优先级,目前还存在待优化的地方,现在只能从零开始,一直+1,中间不能中断不能重复。

二、实现排序工具类

public class MyComparatorUntil {public static List<?> sort(List<?> list) {// 校验if (list == null || list.size() == 0) {return list;}// 通过反射获取类Object t = list.get(0);Class<?> cls = t.getClass();// 获取所有字段Field[] fields = cls.getDeclaredFields();List<String> fieldNames = new ArrayList<>();for (Field field : fields) {if (field.isAnnotationPresent(MySort.class)) {MySort sort = field.getAnnotation(MySort.class);// 此处需要优化顺序问题 TODOfieldNames.add(sort.value(), field.getName());}}if (fieldNames.size() == 0) {return list;}list.sort((o1, o2) -> {Class<?> o1cls = o1.getClass();Class<?> o2cls = o2.getClass();for (String name : fieldNames) {try {// 获取属性值Field o1clsDeclaredField = o1cls.getDeclaredField(name);Field o2clsDeclaredField = o2cls.getDeclaredField(name);o1clsDeclaredField.setAccessible(true);Object value1 = o1clsDeclaredField.get(o1);o2clsDeclaredField.setAccessible(true);Object value2 = o2clsDeclaredField.get(o2);if (value1.equals(value2)) {continue;}// 需要优化比较方法 TODOif (value1 instanceof Integer) {return ((Integer) value1).compareTo((Integer) value2);} else if(value1 instanceof String) {return ((String) value1).compareTo((String) value2);}} catch (NoSuchFieldException | IllegalAccessException e) {e.printStackTrace();}}return 0;});return list;}}

有两处TODO的地方,第一个就是上面说的,排序优先级的问题需要优化。

第二个是目前没有好的方法直接比较两个Object的值大小,所以只能根据类型判断比较,此处简化,只写了Integer和String的类型。

三、测试

新建实体类Student

public class Student {Student(int age, int sex, String name) {this.age = age;this.sex = sex;this.name = name;}@MySort()private int age;@MySort(1)private int sex;@MySort(2)private String name;public int getAge() {return age;}public void setAge(int age) {this.age = age;}public int getSex() {return sex;}public void setSex(int sex) {this.sex = sex;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Student{" +"age=" + age +", sex=" + sex +", name='" + name + '\'' +'}';}}

在想要参与排序的属性上添加注解。

写main方法测试

public static void main(String[] args) {List<Student> list = new ArrayList<>();list.add(new Student(4, 1, "zhangshan"));list.add(new Student(2, 1, "lisi"));list.add(new Student(1, 1, "wangwu"));list.add(new Student(1, 0, "chuchu"));list.add(new Student(1, 1, "kiki"));MyComparatorUntil.sort(list);System.out.println(list);}

输出结果

[Student{age=1, sex=0, name='chuchu'}, Student{age=1, sex=1, name='kiki'}, Student{age=1, sex=1, name='wangwu'}, Student{age=2, sex=1, name='lisi'}, Student{age=4, sex=1, name='zhangshan'}]

如果觉得《结合自定义注解 java反射和comparator实现对象的排序》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。