一、 Lambda表达式对List对象实现多个动态属性排序
java">package com.example.gateway;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;/*** @author wux* @version 1.0.0* @description lambda表达式对List对象实现多个动态属性排序* 场景一:javaObject集合转JSONObject集合,动态指定多个要排序的字段* 场景二:javaObject集合, 动态指定多个要排序的字段* 场景三:JSONObject集合, 动态指定多个要排序的字段* @date 2024/11/29 10:25*/
public class Test2 {public static void main(String[] args) throws Exception {System.out.println("=============场景一:javaObject集合转JSONObject集合,动态指定多个要排序的字段===============");javaObjectToJsonObjectList().stream().forEach(System.out::println);System.out.println("==============场景二:javaObject集合, 动态指定多个要排序的字段==============");javaObjectList().stream().forEach(System.out::println);System.out.println("==============场景三:JSONObject集合, 动态指定多个要排序的字段==============");jsonObjects().stream().forEach(System.out::println);}private static List<WxObj> javaObjectList() throws NoSuchMethodException {WxObj a = new WxObj("w",10.00,20.00,10.00,20.00,10.00);WxObj b = new WxObj("w",10.00,20.00,12.00,20.00,10.00);WxObj c = new WxObj("w",12.00,10.00,10.00,20.00,10.00);WxObj d = new WxObj("w",12.00,20.00,10.00,20.00,10.00);List<WxObj> list = new ArrayList<WxObj>();list.add(a);list.add(b);list.add(c);list.add(d);List<String> sortProperties = new ArrayList<>();//动态指定要排序的属性字段//此处可以根据业务需要传具体字段,此处测试就先写死sortProperties.add("ys1");sortProperties.add("ys2");sortProperties.add("ys3");Map<String, Boolean> sortOrders = new HashMap<>();//动态指定属性字段对应的排序顺序(true表示降序,false表示升序)//此处可以根据业务传具体字段的具体排序方式,此处测试就先写死sortOrders.put("ys1", false);sortOrders.put("ys2", true);sortOrders.put("ys3", true);anyProperListOfReflectSort(list, sortProperties, sortOrders);return list;}private static List<JSONObject> jsonObjects() {List<JSONObject> jsonList = new ArrayList<>();// 添加JSONObject对象到List中JSONObject json1 = new JSONObject();json1.put("id", 1);json1.put("name", "Alice");json1.put("age", 25);json1.put("color", 11.0);JSONObject json2 = new JSONObject();json2.put("id", 2);json2.put("name", "Alice");json2.put("age", 25);json2.put("color", 10.0);JSONObject json3 = new JSONObject();json3.put("id", 3);json3.put("name", "Bob");json3.put("age", 20);json3.put("color", 13.0);jsonList.add(json1);jsonList.add(json2);jsonList.add(json3);List<String> sortProperties = new ArrayList<>();//动态指定要排序的属性字段//此处可以根据业务需要传具体字段,此处测试就先写死sortProperties.add("name");sortProperties.add("age");sortProperties.add("color");Map<String, Boolean> sortOrders = new HashMap<>();//动态指定属性字段对应的排序顺序(true表示降序,false表示升序)//此处可以根据业务传具体字段的具体排序方式,此处测试就先写死sortOrders.put("name", true);sortOrders.put("age", true);sortOrders.put("color", true);List<JSONObject> jsonObjects = anyProperListSort(jsonList, sortProperties, sortOrders);return jsonObjects;}/*** 场景一:javaObject集合 转JSONObject集合,动态指定多个要排序的字段* @return*/private static List<WxObj> javaObjectToJsonObjectList() {WxObj a = new WxObj("w",10.00,20.00,10.00,20.00,10.00);WxObj b = new WxObj("w",10.00,20.00,12.00,20.00,10.00);WxObj c = new WxObj("w",12.00,10.00,10.00,20.00,10.00);WxObj d = new WxObj("w",12.00,20.00,10.00,20.00,10.00);List<WxObj> list = new ArrayList<WxObj>();list.add(a);list.add(b);list.add(c);list.add(d);List<String> sortProperties = new ArrayList<>();//动态指定要排序的属性字段//此处可以根据业务需要传具体字段,此处测试就先写死sortProperties.add("ys1");sortProperties.add("ys2");sortProperties.add("ys3");Map<String, Boolean> sortOrders = new HashMap<>();//动态指定属性字段对应的排序顺序(true表示降序,false表示升序)//此处可以根据业务传具体字段的具体排序方式,此处测试就先写死sortOrders.put("ys1", false);sortOrders.put("ys2", true);sortOrders.put("ys3", true);List<JSONObject> json = new ArrayList<>();for (WxObj wxObj : list) {JSONObject o = JSONObject.parseObject(JSON.toJSONString(wxObj));json.add(o);}List<JSONObject> jsonObjects = anyProperListSort(json, sortProperties, sortOrders);List<WxObj> wxObjs = new ArrayList<>();jsonObjects.stream().forEach(e -> {wxObjs.add(JSONObject.toJavaObject(e, WxObj.class));});return wxObjs;}/*** 按任意给定集合进行排序,升序或降序由flag决定** @param list* @param sortProperties* @param sortOrders* @return*/@SuppressWarnings("unchecked")public static List<JSONObject> anyProperListSort(List<JSONObject> list, List<String> sortProperties, Map<String, Boolean> sortOrders) {Comparator<JSONObject> comparator = null;for (int i = 0; i < sortProperties.size(); i++) {final int propertyIndex = i;Comparator<JSONObject> propertyComparator = Comparator.comparing((JSONObject o) -> o.getString(sortProperties.get(propertyIndex)),String.CASE_INSENSITIVE_ORDER);if (sortOrders.get(sortProperties.get(propertyIndex))) {propertyComparator = propertyComparator.reversed();}if (comparator == null) {comparator = propertyComparator;} else {comparator = comparator.thenComparing(propertyComparator);}}Collections.sort(list, comparator);return list;}/*** 按任意给定集合进行排序,升序或降序由flag决定** @param list 对象* @param sortProperties* @param sortOrders* @return*/private static void anyProperListOfReflectSort(List<WxObj> list, List<String> sortProperties, Map<String, Boolean> sortOrders) throws NoSuchMethodException {// 构建Comparator链Comparator<WxObj> comparator = null;for (int i = 0; i < sortProperties.size(); i++) {final int propertyIndex = i;Class clazz = WxObj.class;Method method = clazz.getMethod("get" + sortProperties.get(propertyIndex).substring(0, 1).toUpperCase() + sortProperties.get(propertyIndex).substring(1));Comparator<WxObj> propertyComparator = Comparator.comparing(wxObj -> {try {return (double)method.invoke(wxObj);} catch (IllegalAccessException | InvocationTargetException e) {throw new RuntimeException(e);}});if (sortOrders.get(sortProperties.get(propertyIndex))) {propertyComparator = propertyComparator.reversed();}if (comparator == null) {comparator = propertyComparator;} else {comparator = comparator.thenComparing(propertyComparator);}}Collections.sort(list, comparator);}@Data@AllArgsConstructor@NoArgsConstructorstatic class WxObj {private String wxObj;private Double ys1;private Double ys2;private Double ys3;private Double ys4;private Double ys5;}
}
二、 按任意属性进行排序(单个属性)
java">package com.example.gateway;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;/*** @author wux* @version 1.0.0* @description 按任意属性进行排序(单个属性)* @date 2024/11/28 16:24*/
public class SortUtil {public static void main(String[] args) {WxObj a = new WxObj("w",10.00,20.00,10.00,20.00,10.00);WxObj b = new WxObj("w",10.00,10.00,10.00,20.00,10.00);WxObj c = new WxObj("w",12.00,10.00,10.00,20.00,10.00);WxObj d = new WxObj("w",12.00,20.00,10.00,20.00,10.00);List<WxObj> list = new ArrayList<WxObj>();list.add(a);list.add(b);list.add(c);list.add(d);anyProperSort(list, "ys1", true);list.stream().forEach(System.out::println);}/*** @description 按任意属性进行排序(单个属性)* @author wux* @date 2024/12/11 14:35* @version 1.0.0*/@Data@NoArgsConstructor@AllArgsConstructorstatic class AnyProperComparator implements Comparator<Object> {private String properName;// 根据此关键字属性排序private boolean flag;// 为true的时候是正序,为false的时候是倒序/*** 实现Comparator的对比方法** @param r1* @param r2*/@Override@SuppressWarnings("unchecked")public int compare(Object r1, Object r2) {Class c = r1.getClass();double result = 0;try {Field field = c.getDeclaredField(properName);String classType = field.getType().getSimpleName();Method method = null;// 这里仅根据方法的返回值类型的名称来判定,比较方便if ("String".equals(classType)) {method = c.getMethod("get" + properName.substring(0, 1).toUpperCase() + properName.substring(1), new Class[] {});if (flag) {result = ((String) method.invoke(r1)).compareTo((String) method.invoke(r2));} else {result = ((String) method.invoke(r2)).compareTo((String) method.invoke(r1));}} else if ("Integer".equals(classType) || "int".equals(classType)) {method = c.getMethod("get" + properName.substring(0, 1).toUpperCase() + properName.substring(1), new Class[] {});if (flag) {result = ((Integer) method.invoke(r1)) - ((Integer) method.invoke(r2));} else {result = ((Integer) method.invoke(r2)) - ((Integer) method.invoke(r1));}} else if ("Double".equals(classType) || "double".equals(classType)) {method = c.getMethod("get" + properName.substring(0, 1).toUpperCase() + properName.substring(1), new Class[] {});if (flag) {result = ((Double) method.invoke(r1)) - ((Double) method.invoke(r2));} else {result = ((Double) method.invoke(r2)) - ((Double) method.invoke(r1));}} else if ("Float".equals(classType) || "float".equals(classType)) {method = c.getMethod("get" + properName.substring(0, 1).toUpperCase() + properName.substring(1), new Class[] {});if (flag) {result = ((Float) method.invoke(r1)) - ((Float) method.invoke(r2));} else {result = ((Float) method.invoke(r2)) - ((Float) method.invoke(r1));}} else {System.out.println("属性排序只支持数据类型和String类型,其它类型暂不支持。");result = -100;}} catch (SecurityException | NoSuchFieldException | InvocationTargetException | NoSuchMethodException | IllegalArgumentException | IllegalAccessException e ) {e.printStackTrace();}// 确定返回值if (result > 0) {return 1;} else if (result < 0) {return -1;}return 0;}}/*** 按任意给定的字段进行排序,升序或降序由flag决定** @param list* @param properName* @param flag* @return*/@SuppressWarnings("unchecked")public static List<WxObj> anyProperSort(List<WxObj> list, String properName, boolean flag) {AnyProperComparator comparator = new AnyProperComparator(properName, flag);Collections.sort(list, comparator);return list;}
}