1.实现Comparator进行排序
创建需要排序对象
/**
* @author wangli
* @create 2022-08-17 17:17
*/
@Data
public class TotalNumDto {
@ApiModelProperty("工单总量")
private Integer workNum;
@ApiModelProperty("同比数")
private Integer yoyNum;
@ApiModelProperty("环比数")
private Integer qoqNum;
}
实现Comparator的compare方式实现排序
@Test
public void test2(){
List<TotalNumDto> totalNumDtoList = new ArrayList<>();
for (int i = 0; i < 3; i++) {
TotalNumDto totalNumDto = new TotalNumDto();
totalNumDto.setWorkNum(i*2+1);
totalNumDtoList.add(totalNumDto);
}
System.out.println("排序前 = " + totalNumDtoList);
Collections.sort(totalNumDtoList, new Comparator<TotalNumDto>() {
@Override
public int compare(TotalNumDto o1, TotalNumDto o2) {
//顺序
//return o1.getWorkNum()-o2.getWorkNum();
//逆序
return o2.getWorkNum()-o1.getWorkNum();
}
});
System.out.println("排序后 = " + totalNumDtoList);
}
打印结果如下
排序前 = [
TotalNumDto(workNum=1, yoyNum=null, qoqNum=null),
TotalNumDto(workNum=3, yoyNum=null, qoqNum=null),
TotalNumDto(workNum=5, yoyNum=null, qoqNum=null)]
排序后 = [TotalNumDto(workNum=5, yoyNum=null, qoqNum=null),
TotalNumDto(workNum=3, yoyNum=null, qoqNum=null),
TotalNumDto(workNum=1, yoyNum=null, qoqNum=null)]
比较它的两个参数的顺序。返回负整数、零或正整数,因为第一个参数小于、等于或大于第二个
当compare方法返回1时需要交换这两个数的位置,通过算法循环从而达到不断交换位置实现排序
2.实现Comparable接口,然后重写CompareTo方法。
编写对象实现Comparable接,重写CompareTo
/**
* @author wangli
* @create 2022-08-17 17:17
*/
@Data
public class TotalNumDto implements Comparable<TotalNumDto> {
@ApiModelProperty("工单总量")
private Integer workNum;
@ApiModelProperty("同比数")
private Integer yoyNum;
@ApiModelProperty("环比数")
private Integer qoqNum;
public TotalNumDto(Integer workNum, Integer yoyNum, Integer qoqNum) {
this.workNum = workNum;
this.yoyNum = yoyNum;
this.qoqNum = qoqNum;
}
@Override
public int compareTo(TotalNumDto o) {
//按照工单总量排序
int i = this.getWorkNum().compareTo(o.getWorkNum());
//如果工单总量一致按照同比数排序
if (i == 0) {
i = this.getYoyNum().compareTo(o.getYoyNum());
//如果工同比数一致按照环比数排序
if (i == 0) {
i = this.getQoqNum().compareTo(o.getQoqNum());
}
}
return i;
}
}
直接调用方法实现排序
@Test
public void test3(){
List<TotalNumDto> totalNumDtoList = new ArrayList<>();
totalNumDtoList.add(new TotalNumDto(3,4,12));
totalNumDtoList.add(new TotalNumDto(3,2,13));
totalNumDtoList.add(new TotalNumDto(9,1,14));
System.out.println("排序前");
totalNumDtoList.forEach(System.out::println);
System.out.println("排序后");
totalNumDtoList.stream().sorted().forEach(System.out::println);
}
按顺序排序输出
3.使用字段对对象数组进行排序
此处是自己编写的工具类,通过输入list对象数组和需要排序的字段以及排序方式,进行排序
/**
* @author wangli
* @create 2022-08-17 14:13
*/
public class SortListUtil<E> {
public void SortByField(Map<String, Object> data, List<E> list){
if (data.containsKey("sortField")&&data.containsKey("sort")){
String method = (String) data.get("sortField");
String order = (String) data.get("sort");
Sort(list,method,order);
}
}
/**
* @param list 需要排序的list
* @param method 需要排序的字段
* @param order 排序的顺序
*/
public void Sort(List<E> list, final String method, final String order) {
Collections.sort(list, new Comparator<E>() {
@Override
public int compare(E o1, E o2) {
int ret = 0;
try {
Method method1 = o1.getClass().getMethod(method, null);
Method method2 = o2.getClass().getMethod(method, null);
//倒序
if (StringUtils.isNotEmpty(order) && "desc".equalsIgnoreCase(order)) {
ret =Integer.parseInt(method2.invoke(o2, null).toString())>
Integer.parseInt(method1.invoke(o1, null).toString())?1:-1;
}
else {
ret = Integer.parseInt(method1.invoke(o1, null).toString())>
Integer.parseInt(method2.invoke(o2, null).toString())?1:-1;
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return ret;
}
});
}
}
调用工具类
@Override
public List<MonthlyDto> monthlySearch(Map<String, Object> data) {
List<MonthlyDto> dtos = new ArrayList<>();
log.info("诉求分类(月度)排序前:{}",dtos);
SortListUtil<MonthlyDto> totalDtoSortListUtil = new SortListUtil<>();
totalDtoSortListUtil.Sort(dtos,"getWorkNum","desc");
totalDtoSortListUtil.SortByField(data,dtos);
log.info("诉求分类(月度)排序后:{}",dtos);
return dtos;
}
因为在jdk6和jdk7底层排序方法有些不同,所以在有些情况下会报错Comparison method violates its general contract!
在 JDK7 版本以上,Comparator 要满足自反性,传递性,对称性,不然 Arrays.sort,Collections.sort
回到上面的例子,假设存在三个元素:stu1, null,stu2,则
compare(stu1, null)= 0,
compare(null, stu2) = 0,
compare(stu1,stu2) =1 很明显违反了传递性原则。
可以将代码修改为
public void SortByMap(List<E> list, final String method, final String order) {
Collections.sort(list, new Comparator<E>() {
@Override
public int compare(E o1, E o2) {
try {
Method method1 = o1.getClass().getMethod(method, null);
Method method2 = o2.getClass().getMethod(method, null);
if (StringUtils.isNotEmpty(order) && "asc".equalsIgnoreCase(order)) {
if (o1 == null) {
if (o2 == null) {
return 0;
}
return 1;
}
return Integer.parseInt(method2.invoke(o1, null).toString()) -
Integer.parseInt(method1.invoke(o2, null).toString());
}else {
if (o2 == null) {
if (o1 == null) {
return 0;
}
return 1;
}
return Integer.parseInt(method2.invoke(o2, null).toString()) -
Integer.parseInt(method1.invoke(o1, null).toString());
}
} catch (Exception e){
e.printStackTrace();
log.info(e);
return 0;
}
}
});
}
4.根据某一属性对List<List<String>>进行排序
/**
* @param data 输入需要排序的参数
* @param yList 需要排序的List<List<String>>
* @param s 需要过滤不排序的信息
* @param i list中需要排序的第几个字段
* @return 排序后的List<List<String>>
*/
public static List<List<String>> sortContainList(Map<String, Object> data, List<List<String>> yList,String s,int i) {
if (Objects.equals(data.get("sort"), "asc")) {
yList.sort(Comparator.comparingInt(o -> Integer.parseInt(o.get(i))));
return yList;
} else {
Collections.sort(yList, (o1, o2) -> {
if (o1.get(i).equals(s)||o2.get(i).equals(s)){
return 1;
}else {
return Integer.parseInt(o2.get(i)) - Integer.parseInt(o1.get(i));
}
});
}
return yList;
}