主要通過反射拿到對象的屬性,然後重寫sort方法,比較屬性值。代碼如下:
package cn.sinobest.sdg.util;
import java.lang.reflect.Field;
import java.util.*;
/**
* @description 集合工具類
* @author: dengweiping
* @time: 2020/6/1 14:49
*/
public class ListUtil {
/**
* 根據指定屬性升序排序
*
* @param list 集合
* @param propertyName 屬性名
* @param <T>
* @return
*/
public static <T> List<T> sortAsc(List<T> list, String propertyName) {
return sort(list, propertyName, "asc", false);
}
/**
* 根據指定屬性升序排序,忽略大小寫
*
* @param list 集合
* @param propertyName 屬性名
* @param <T>
* @return
*/
public static <T> List<T> sortAscIgnoreCase(List<T> list, String propertyName) {
return sort(list, propertyName, "asc", true);
}
/**
* 根據指定屬性降序排序
*
* @param list 集合
* @param propertyName 屬性名
* @param <T>
* @return
*/
public static <T> List<T> sortDesc(List<T> list, String propertyName) {
return sort(list, propertyName, "desc", false);
}
/**
* 根據指定屬性降序排序,忽略大小寫
*
* @param list 集合
* @param propertyName 屬性名
* @param <T>
* @return
*/
public static <T> List<T> sortDescIgnoreCase(List<T> list, String propertyName) {
return sort(list, propertyName, "desc", true);
}
/**
* 根據指定方式排序
*
* @param list 集合
* @param propertyName 屬性名
* @param sortType 排序方式 asc:升序 desc:降序
* @param <T>
* @return
*/
private static <T> List<T> sort(List<T> list, String propertyName, String sortType, boolean ignoreCase) {
Collections.sort(list, (Comparator<Object>) (o1, o2) -> {
try {
Field field1 = o1.getClass().getDeclaredField(propertyName);
Field field2 = o2.getClass().getDeclaredField(propertyName);
//打開私有訪問
field1.setAccessible(true);
field2.setAccessible(true);
String type = field1.getType().getName();
Object obj1 = field1.get(o1);
Object obj2 = field2.get(o2);
if (obj1 == null) {
return -1;
} else if (obj2 == null) {
return 1;
}
boolean isAsc = "asc".equals(sortType);
switch (type) {
case "int":
return isAsc ? ((int) obj1 - (int) obj2) : ((int) obj2 - (int) obj1);
case "long":
case "java.lang.Long":
return (long) obj1 > (long) obj2 ? (isAsc ? 1 : -1) : (isAsc ? -1 : 1);
case "double":
case "java.lang.Double":
return (double) obj1 > (double) obj2 ? (isAsc ? 1 : -1) : (isAsc ? -1 : 1);
case "float":
case "java.lang.Float":
return (float) obj1 > (float) obj2 ? (isAsc ? 1 : -1) : (isAsc ? -1 : 1);
case "java.lang.String":
//循環比較次數以字符串短的爲準
int length = obj1.toString().length() < obj2.toString().length() ? obj1.toString().length() : obj2.toString().length();
//是否忽略大小寫
char[] charArray1 = ignoreCase ? obj1.toString().toLowerCase().toCharArray() : obj1.toString().toCharArray();
char[] charArray2 = ignoreCase ? obj2.toString().toLowerCase().toCharArray() : obj2.toString().toCharArray();
//比較字符串的ASCII碼值
for (int i = 0; i < length; i++) {
if ((byte) charArray1[i] > (byte) charArray2[i]) {
return isAsc ? 1 : -1;
} else if ((byte) charArray1[i] < (byte) charArray2[i]) {
return isAsc ? -1 : 1;
}
}
//若相同長度部分的字符串都相等,則根據字符串長度比較
return isAsc ? (charArray1.length - charArray2.length) : (charArray2.length - charArray1.length);
case "java.util.Date":
Date d1 = (Date) obj1;
Date d2 = (Date) obj2;
return d1.getTime() > d2.getTime() ? (isAsc ? 1 : -1) : (isAsc ? -1 : 1);
default:
throw new RuntimeException("暫不支持 " + type + " 類型的屬性排序");
}
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
return 0;
});
return list;
}
}
更多工具類可以查看我的博客:Java字符串、集合等工具類合集
項目源碼地址:全球同性交友網站