Collections.sort工具类,对list中的对象进行排序
在日常写代码的时候,经常会对数据进行排序,如果list里面存放的是简单的包装类,即里面存放的是Integer,String如[1,2,5,3,8]这样子的简单列表的话就直接使用Collections.sort(list)
就可以实现排序了,这个排序是正序的,但是如果需要倒序怎么办呢?这个时候可以用Collections
里面的一个方法Collections.reverse()
方法,这个方法实现的是列表的反转,注意:这个方法是反转列表,而不是直接在无序列表下直接倒叙。也就是说如果你的列表无序时是[1,3,2,5],反转之后就是,[5,2,3,1]。这里就写代码了,我在下边放我参考的一些大佬的博客。
而要是list里面放的不是简单的包装,而是存放的是一个对象的话,那么就要让这个对象是课比较的,让对象实现可比较的方法很简单就是让它实现Compareble<T>
接口,然后重写里面的compareTo()
方法就可以了。
- 例如
@Getter
@Setter
@ToString
public class Test1 implements Comparable<Test1>{
private String name;
private int age;
@Override
public int compareTo(Test1 test1) {
return this.age - test1.getAge();//正序
//return test1.getAge() - this.getAge();//倒叙
}
}
用这个实现排序其实蛮简单的,就是每次实现起来有一点太麻烦了,如果这个类里面有多个值需要在不同的地方进行比较的话,那么这个方法就不太适用了,这句话好像没太清楚,也就是说这玩意虽然简单,但是我觉得不方便。
- 所以我看了这位博主的博客看到了他最后一步的工具类我觉得这玩意好像是挺方便,就去按照教程敲了敲,但是不敲还好,一敲问题就出来了。问题是我自己的,博主代码很好没有问题的。因为先前工具类是抄的我就直接放代码了。
package com.hungteshun.util;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.apache.commons.lang.StringUtils;
/**
* @author hungteshun
* @description:
* @date 2018/11/31 22:23
*/
public class SortListUtil<E> {
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 = method2.invoke(o2, null).toString().compareTo(method1.invoke(o1, null)
.toString());
}
else {
ret = method1.invoke(o1, null).toString()
.compareTo(method2.invoke(o2, null).toString());
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return ret;
}
});
}
}
原封不动的抄过来了,之后我就去写了一个测试类来跑,测试类被我改了所以没有代码了,就放之前的截图吧
-
这是控制台输出的结果。。
-
可以看到最后两次返回值的输出,ret的返回值是负数,也就意味着13,比2,和6还要小,也就是因为这个导致了排序的错误。也因为这样一个简单的测试把我搞崩了2天,各种看源码,百度,都没有解决,直到今天才终于知道错在哪儿了。
原因:
- 我的test测试类里面的age是int类型的,然后博主写的类型是Integer类型的我不知道这个有没有影响,没去测试,感兴趣可以去测试一下
- 博主测试类里面比较大小用的
compareTo()
方法,然后用toString()
把得到的结果转换为String类型,对String 类里面的方法compareTo()
官方的解释是
如果参数字符串等于此字符串,则返回值 0;
如果此字符串小于字符串参数,则返回一个小于 0 的值;
如果此字符串大于字符串参数,则返回一个大于 0 的值。
如果第一个字符和参数的第一个字符不等,结束比较,返回第一个字符的ASCII码差值。
如果第一个字符和参数的第一个字符相等,则以第二个字符和参数的第二个字符做比较,以此类推,直至不等为止,返回该字符的ASCII码差值。 如果两个字符串不一样长,可对应字符又完全一样,则返回两个字符串的长度差值。
- 因为toString的原因,13,和2只比价了第一个字符所以返回的值13比2小。于是乎我去重新写了一下我需要的工具类
/**
* 功能描述
*List排序工具类针对Int值
* @author 27180
* @date 2022/07/01 11:23
*/
import org.thymeleaf.util.StringUtils;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* @author 27180
* @date 2022/7/1 11:23
* @param 参数说明:list 传入的列表, method 对象里面取值的方法 , order 排序方式【desc倒叙其他的正序】
*/
public class SortListUtil<E> {
public void sort(List<E> list,final String method ,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);//取出的东西是o1里传入方法名字的返回值
Method method2 = o2.getClass().getMethod(method,null);//么个取出的是o2传入方法的返回值
Object invoke = method2.invoke(o1, null);
//倒叙 排列
if (!StringUtils.isEmpty(order) && "desc".equalsIgnoreCase(order)){
//ret = method2.invoke(o2,null).toString().compareTo(method1.invoke(o1,null).toString());
Object o = method1.invoke(o1, null);
int a = Integer.parseInt(o.toString());
o = method2.invoke(o2,null);
int b = Integer.parseInt(o.toString());
ret = b - a;
}else {
//ret = method1.invoke(o1,null).toString().compareTo(method2.invoke(o2,null).toString());
Object o = method1.invoke(o1, null);
int a = Integer.parseInt(o.toString());
o = method2.invoke(o2,null);
int b = Integer.parseInt(o.toString());
System.out.println(a+"++++++++"+b);//这个用来看ab分别的值
ret = a-b;
System.out.println(ret+"这是返回的值");
System.out.println(list+"这是还没有交换的列表,下一个值的输出就是上一个交换之后的结果!!");
}
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
return ret;
}
});
}
}
这个就是我需要的int对于这个排序的工具类,我看源码不知道sort是怎么排序的,我用控制台输出的结果也没太明白他是怎么排序的,因为算法还没怎么学,所以如果有大佬知道可以解释一下嘛。这是控制台输出的结果。
这个我改的这个工具类只能适用于返回值是int类型的还是不够全能,要是想要在全能一点的话,可以在形参列表里面加一个参数判断,在下边再写一个if函数把区分一下是什么类型,应该就可以了。
这个就是我需要的int对于这个排序的工具类,我看源码不知道sort是怎么排序的,我用控制台输出的结果也没太明白他是怎么排序的,因为算法还没怎么学,所以如果有大佬知道可以解释一下嘛。这是控制台输出的结果。
这个我改的这个工具类只能适用于返回值是int类型的还是不够全能,要是想要在全能一点的话,可以在形参列表里面加一个参数判断,在下边再写一个if函数把区分一下是什么类型,应该就可以了。