问题描述:
需对页面列表字段进行排序,这些字段都来自不同的表,因此在sql里使用order by 排序是不可行的,只能对list列表使用stream流排序。又因为需要排序的字段较多,在代码里频繁写if else 会显得代码比较繁琐不美观,所以考虑用反射,将反射和stream流排序结合起来对问题进行解决。
解决步骤:
1)定义一个枚举类,根据前端传入的orderWay字段确定要排序的字段名称。
2)在list装载的信息类里定义一个静态方法,该方法能够利用反射根据字段名称动态获取该字段对应的getter方法。
3)对需要排序的list,调用stream流的sort方法,在sort方法里重写lambda表达式,调用步骤2所得的getter方法的invoke方法获取要比较的两个元素的排序字段值,实现排序。
核心代码:
public static Method getFieldName(Class<?> clazz, String name) {
String methodName = "";
Method method = null;
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
if (name.equals(field.getName())) {
methodName = "get" + Character.toUpperCase(name.charAt(0)) + name.substring(1);
}
}
try {
method = User.class.getMethod(methodName);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
return method;
}
//将list按某字段排序
Method method = User.getFieldName(User.class, "age");
Integer orderType = 1;
List<User> collect = list.stream().sorted(
(e1, e2) -> {
try {
Integer invoke1 = (Integer)method.invoke(e1);
Integer invoke2 = (Integer)method.invoke(e2);
if (orderType == 1) {
return invoke1 - invoke2;
}
return invoke2 - invoke1;
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
).collect(Collectors.toList());