前言
对于基本类型的集合排序,可以直接借助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=左手))]