在项目开发中,我们经常要对一组数据进行排序,或者升序或者降序,在Java中排序有多种方式,最土的方式就是自己写排序算法,比如冒泡排序、快速排序、二叉树排序等,但一般不需要自己写,JDK已经为我们提供了很多的排序算法,我们采用”拿来主义” 就成了。在Java中,要想给数据排序,有两种实现方式,一种是实现Comparable接口,一种是实现Comparator接口,这两者有什么区别呢?我们来看一个例子,就比如给公司职员按照工号排序吧,先定义一个职员类代码,如下所示:
!!!Comparable接口可以作为实现类的默认排序算法,Comparator接口则是一个类的扩展排序工具
- public class Employee implements Comparable<Employee>{
- private int id;
- private String name;
- private Position position;
- public Employee(int id,String name,Position position){
- this.id = id;
- this.name = name;
- this.position = position;
- }
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public Position getPosition() {
- return position;
- }
- public void setPosition(Position position) {
- this.position = position;
- }
- //我是按照Id升序排列
- @Override
- public int compareTo(Employee o) {
- if(this.id > o.id){
- return 1;
- }else if(this.id < o.id){
- return -1;
- }else
- return 0;
- }
- public String toString(){
- return “编号:” + this.id + “姓名:” + this.name + “职位:” + this.position;
- }
- enum Position{
- Boss,Manager,Staff
- }
- }
public class Employee implements Comparable<Employee>{
private int id;
private String name;
private Position position;
public Employee(int id,String name,Position position){
this.id = id;
this.name = name;
this.position = position;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Position getPosition() {
return position;
}
public void setPosition(Position position) {
this.position = position;
}
//我是按照Id升序排列
@Override
public int compareTo(Employee o) {
if(this.id > o.id){
return 1;
}else if(this.id < o.id){
return -1;
}else
return 0;
}
public String toString(){
return "编号:" + this.id + "姓名:" + this.name + "职位:" + this.position;
}
enum Position{
Boss,Manager,Staff
}
}
编写客户端程序进行测试:
- public class Client {
- public static void main(String[] args){
- List<Employee> list = new ArrayList<>(5);
- list.add(new Employee(1004,“sd”,Employee.Position.Staff));
- list.add(new Employee(1005,“sa”, Employee.Position.Staff));
- list.add(new Employee(1002,“ls”, Employee.Position.Manager)) ;
- list.add(new Employee(1003,“ww”, Employee.Position.Manager));
- list.add(new Employee(1001,“zs”, Employee.Position.Boss));
- System.out.println(List.class);
- //按照id升序排列,如果想按照名字升序排列就要用到Comparator
- Collections.sort(list);
- for(Employee e:list){
- System.out.println(e);
- }
- }
- }
public class Client {
public static void main(String[] args){
List<Employee> list = new ArrayList<>(5);
list.add(new Employee(1004,"sd",Employee.Position.Staff));
list.add(new Employee(1005,"sa", Employee.Position.Staff));
list.add(new Employee(1002,"ls", Employee.Position.Manager)) ;
list.add(new Employee(1003,"ww", Employee.Position.Manager));
list.add(new Employee(1001,"zs", Employee.Position.Boss));
System.out.println(List.class);
//按照id升序排列,如果想按照名字升序排列就要用到Comparator
Collections.sort(list);
for(Employee e:list){
System.out.println(e);
}
}
}
这里只是依据id进行的排序,这就是Employee默认的排序算法,
但是,有时候我们希望按照职位来排序,职位一样的话我在根据id排序那怎么做呢?此时,重构Employee类已经不合适了,Employee已经是一个稳定类,为了排序功能修改它不是一个好办法,哪有什么好的解决办法吗?
有办法,看Collections.sort方法,它有一个重载方法Collections.sort(List<T> list, Comparator<? super T> c),可以接收一个Comparator实现类,这下就好办了,在Employee类中增加一段代码即可代码如下:
- static class PositionComparator implements Comparator<Employee>{
- @Override
- public int compare(Employee o1, Employee o2) {
- int len1 = o1.getPosition().toString().length();
- int len2 = o2.getPosition().toString().length();
- //找到他们两个长度的最小值
- int minLen = Math.min(len1,len2);
- char[] v1 = o1.getPosition().toString().toCharArray();
- char[] v2 = o2.getPosition().toString().toCharArray();
- int k = 0;
- while(k < minLen){
- char vp = v1[k];
- char vl = v2[k];
- if(vp != vl){
- return vl - vp;
- }else{
- break;
- }
- }
- //如果职位相同再按照工号排序
- if(o1.getId() > o2.getId()){
- return -1;
- }else if(o1.getId() < o2.getId()){
- return 1;
- }else
- return 0;
- }
- }
static class PositionComparator implements Comparator<Employee>{
@Override
public int compare(Employee o1, Employee o2) {
int len1 = o1.getPosition().toString().length();
int len2 = o2.getPosition().toString().length();
//找到他们两个长度的最小值
int minLen = Math.min(len1,len2);
char[] v1 = o1.getPosition().toString().toCharArray();
char[] v2 = o2.getPosition().toString().toCharArray();
int k = 0;
while(k < minLen){
char vp = v1[k];
char vl = v2[k];
if(vp != vl){
return vl - vp;
}else{
break;
}
}
//如果职位相同再按照工号排序
if(o1.getId() > o2.getId()){
return -1;
}else if(o1.getId() < o2.getId()){
return 1;
}else
return 0;
}
}
如果想改变排序方式在compare方法中改变vl,vp的位置就可以办到了
!!!Comparable接口可以作为实现类的默认排序算法,Comparator接口则是一个类的扩展排序工具
参考原文:参考文章