排序工具类,可以根据选定字段排序,同时可以处理null值字段排序,如有自定义可自己新增排序方法替换sorted中的排序方式。
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.comparator.CompareUtil;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* 自定义排序
*
* @author HY
*/
public class ListSortUtil {
/**
* 自定义字段排序
*
* @param list
* @param sortName
* @param tClass
* @param desc
* @param descNull
* @param <T>
*
* @return
*/
public static <T> List<T> sortListByField(List<T> list, String sortName, Class<T> tClass, boolean desc, boolean descNull) {
return list.stream()
.map(convertBeanToMap())
.sorted(getMapComparator(sortName, desc, descNull))
.map(convertMapToBean(tClass))
.collect(Collectors.toList());
}
/**
* 自定义字段排序
*
* @param list
* @param sortName
* @param desc
* @param tClass
* @param <T>
*
* @return
*/
public static <T> List<?> sortListByField(List<T> list, String sortName, boolean desc, Class<T> tClass) {
return sortListByField(list, sortName, tClass, desc, true);
}
/**
* 是否倒序防范
*
* @param sortName
* @param desc
* @param descNull
*
* @return
*/
private static Comparator<Map<String, Object>> getMapComparator(String sortName, boolean desc, boolean descNull) {
if (desc) {
return (o1, o2) -> getCompareUtil(sortName, descNull, o1, o2);
}
return ((Comparator<Map<String, Object>>) (o1, o2) -> getCompareUtil(sortName, descNull, o1, o2)).reversed();
}
/**
* 比较方法
*
* @param sortName 排序字段
* @param descNull null值排序规则
* @param o1
* @param o2
*
* @return
*/
private static int getCompareUtil(String sortName, boolean descNull, Map<String, Object> o1, Map<String, Object> o2) {
return CompareUtil.compare(o1.get(sortName), o2.get(sortName), descNull);
}
private static <T> Function<Map<String, Object>, T> convertMapToBean(Class<T> tClass) {
return map -> BeanUtil.toBean(map, tClass);
}
private static <T> Function<T, Map<String, Object>> convertBeanToMap() {
return BeanUtil::beanToMap;
}
}
测试方法
import com.java.coco.domian.Person;
import org.junit.Before;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
import static com.java.coco.utils.ListSortUtil.sortListByField;
import static org.assertj.core.api.Assertions.assertThat;
/**
* 自定义排序
*
* @author yihur
*/
public class TestSortedStream {
private List<Person> personList;
@Before
public void init_data() {
personList = Arrays.asList(new Person(null, 18), new Person("Peter", 23), new Person("Anda", 23), new Person("David", 12));
}
@Test
public void test_java_stream_sorted_01() {
String sortName = "name";
boolean desc = Boolean.FALSE;
boolean descNull = Boolean.FALSE;
List<Person> persons = sortListByField(personList, sortName, Person.class, desc, descNull);
assertThat(persons.size()).isEqualTo(4);
assertThat(persons.get(0).getName()).isEqualTo("Peter");
assertThat(persons.get(1).getName()).isEqualTo("David");
assertThat(persons.get(2).getName()).isEqualTo("Anda");
assertThat(persons.get(3).getName()).isNull();
}
@Test
public void test_java_stream_sorted_02() {
String sortName = "name";
boolean desc = Boolean.TRUE;
boolean descNull = Boolean.FALSE;
List<Person> persons = sortListByField(personList, sortName, Person.class, desc, descNull);
assertThat(persons.size()).isEqualTo(4);
assertThat(persons.get(0).getName()).isNull();
assertThat(persons.get(1).getName()).isEqualTo("Anda");
assertThat(persons.get(2).getName()).isEqualTo("David");
assertThat(persons.get(3).getName()).isEqualTo("Peter");
}
@Test
public void test_java_stream_sorted_03() {
String sortName = "name";
boolean desc = Boolean.FALSE;
boolean descNull = Boolean.TRUE;
List<Person> persons = sortListByField(personList, sortName, Person.class, desc, descNull);
assertThat(persons.size()).isEqualTo(4);
assertThat(persons.get(0).getName()).isNull();
assertThat(persons.get(1).getName()).isEqualTo("Peter");
assertThat(persons.get(2).getName()).isEqualTo("David");
assertThat(persons.get(3).getName()).isEqualTo("Anda");
}
@Test
public void test_java_stream_sorted_04() {
String sortName = "name";
boolean desc = Boolean.TRUE;
boolean descNull = Boolean.TRUE;
List<Person> persons = sortListByField(personList, sortName, Person.class, desc, descNull);
assertThat(persons.size()).isEqualTo(4);
assertThat(persons.get(0).getName()).isEqualTo("Anda");
assertThat(persons.get(1).getName()).isEqualTo("David");
assertThat(persons.get(2).getName()).isEqualTo("Peter");
assertThat(persons.get(3).getName()).isNull();
}
}
@Data
@AllArgsConstructor
public class Person {
private String name;
private Integer age;
}