List集合排序Comparable与Comparator实现
前言
Comparable和 Comparator有什么区别?相信很多同学在面试过程中会经常遇到这个问题。今天我们就结合实际应用来分析这两个对象的区别。
需求
我们的集合里存放了一批砖石王老五的资料,我们需要对这个集合进行排序,排序的规则就按照年少多金来进行排序。什么是年少多金?也就是说我们先比较年龄,年龄小的排在前面,年龄大的排在后面,年龄相同的,千多的排在前面。
Comparable 实现
使用Comparable 排序的需要实现Comparable 接口中的compareTo方法,在User中我们先
@Data
public class User implements Comparable<User> {
/**
* 名字
*/
private String name;
/**
* 年龄
*/
private int age;
/**
* 金钱
*/
private int money;
public User(){}
public User(String name,int age,int money){
this.name=name;
this.age=age;
this.money=money;
}
@Override
public int compareTo(User user) {
//先根据用户年龄升序排序
int tmp=this.getAge()-user.getAge();
if(tmp==0){
//如果年纪相等,那么在比较钱多钱少,
return user.getMoney()-this.getMoney();
}
return tmp;
}
}
public static void main(String[] args){
List<User> list=new ArrayList<>();
list.add(new User("Aom",38,999999));
list.add(new User("Bom",28,999999));
list.add(new User("Com",18,999999));
list.add(new User("Dom",38,888888));
list.add(new User("Gom",20,666666));
list.add(new User("Eom",28,888888));
list.add(new User("Fom",18,888888));
System.out.println("排序前");
list.forEach(x->System.out.println(x));
Collections.sort(list);
System.out.println("排序后");
list.forEach(x->System.out.println(x));
}
执行main方法输出结果如下所示,集合输出的结果是按照年少多金排序的。可见通过Comparable 实现是可实现我们的排序需求的。
排序前
User(name=Aom, age=38, money=999999)
User(name=Bom, age=28, money=999999)
User(name=Com, age=18, money=999999)
User(name=Dom, age=38, money=888888)
User(name=Gom, age=20, money=666666)
User(name=Eom, age=28, money=888888)
User(name=Fom, age=18, money=888888)
排序后
User(name=Com, age=18, money=999999)
User(name=Fom, age=18, money=888888)
User(name=Gom, age=20, money=666666)
User(name=Bom, age=28, money=999999)
User(name=Eom, age=28, money=888888)
User(name=Aom, age=38, money=999999)
User(name=Dom, age=38, money=888888)
Comparator 实现
Comparator 实现方式则不需要对比较的对象进行修改,经排序的逻辑放在外层。
@Data
public class User {
/**
* 名字
*/
private String name;
/**
* 年龄
*/
private int age;
/**
* 金钱
*/
private int money;
public User(){}
public User(String name,int age,int money){
this.name=name;
this.age=age;
this.money=money;
}
}
排序方法实现
public static void main(String[] args){
List<User> list=new ArrayList<>();
list.add(new User("Aom",38,999999));
list.add(new User("Bom",28,999999));
list.add(new User("Com",18,999999));
list.add(new User("Dom",38,888888));
list.add(new User("Gom",20,666666));
list.add(new User("Eom",28,888888));
list.add(new User("Fom",18,888888));
System.out.println("排序前");
list.forEach(x->System.out.println(x));
Collections.sort(list, new Comparator<User>() {
@Override
public int compare(User o1, User o2) {
int tmp=o1.getAge()-o2.getAge();
if(tmp==0){
return o2.getMoney()-o1.getMoney();
}
return tmp;
}
});
System.out.println("排序后");
list.forEach(x->System.out.println(x));
}
执行main方法运行结果如下,也同样实现了我们的需求。
排序前
User(name=Aom, age=38, money=999999)
User(name=Bom, age=28, money=999999)
User(name=Com, age=18, money=999999)
User(name=Dom, age=38, money=888888)
User(name=Gom, age=20, money=666666)
User(name=Eom, age=28, money=888888)
User(name=Fom, age=18, money=888888)
排序后
User(name=Com, age=18, money=999999)
User(name=Fom, age=18, money=888888)
User(name=Gom, age=20, money=666666)
User(name=Bom, age=28, money=999999)
User(name=Eom, age=28, money=888888)
User(name=Aom, age=38, money=999999)
User(name=Dom, age=38, money=888888)
总结
- Comparable 排序需要在实体中信息接口中的compareTo,这种方式耦合性较高,当需求变更时需要改动的地方较多,比如需求突然变成先按照金额排序,在排序年龄时,我们就需要重写实体的代码,但是实体的代码在其它地方有引用的情况,那么这个坑就有点大了。
- Comparator排序方式将排序逻辑放在外层,我们可以根据实质情况临时调整排序逻辑而不影响实体的结构。从这一点来说个人建议使用Comparator方式进行集合排序。
来源:CSDN
作者:凌飞安
链接:https://blog.csdn.net/lingfeian/article/details/98058405