一、Comparable 接口的使用
Comparable 这个接口对实现它的每个类的对象施加了一个总的排序。这个顺序被称为类的自然排序,和类的compareTo方法称为自然方法。
实现这个接口的可以自动排序的对象列表(list<>)或数组(Object[])可以通过 Collections.sort()或Arrays.sort()方法进行排序。
实现此接口的对象中的元素可以作为排序集中的进行比较的键,而不需要指定比较器。(上述为翻译API中的一段话)。
因为刚好用到排序,并且是需要对整体进行排序可以使用 Comparable 接口。
1、需要进行排序的 pojo 对象需要实现 Comparable 接口,实现自定义的排序方法。
最终的目的:对 Staff 对象,按照对象的年龄属性,与KPI属性的大小进行排序。年龄大的排在前面,年龄相同的 则KPI 高的排在前面
package comparable_test;
/**
* 员工实体
* @author Scott
* @time 2017年9月9日
*/
public class Staff implements Comparable<Staff>{
/** 员工年龄*/
private int age;
/** 员工KPI*/
private int score;
/**
* 构造函数
* @param age
* @param score
*/
public Staff(int age, int score) {
super();
this.age = age;
this.score = score;
}
//比较对象大小时以 参数 作为基准
@Override
public int compareTo(Staff o) {
int i = 0;
if (o.age > this.age) {
i = 1;
} else if (this.age == o.age) {
if (o.score > this.score) {
i = 1;
} else if (o.score < this.score) {
i = -1;
}
} else if (o.age < this.age) {
i = -1;
}
return i;
}
//get set ...
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
2、使用Collections.sort()方法进行整体排序,并输出排序前后的结果
此时是不许要指定一个比较器的
package comparable_test;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class TestSort {
static List<Staff> staffInfos = new ArrayList<Staff>();
public static void main(String[] args) {
staffInfos.add(new Staff(5, 102));
staffInfos.add(new Staff(8, 103));
staffInfos.add(new Staff(4, 104));
staffInfos.add(new Staff(4, 105));
//排序前输出结果
System.out.println("排序前输出结果");
staffInfos.forEach(staff -> {
int age = staff.getAge();
int score = staff.getScore();
System.out.println("年龄:"+ age + "\t\t" + "KPI:" + score);
});
//排序后输出结果
System.out.println("\n"+"排序后输出结果");
Collections.sort(staffInfos);
staffInfos.forEach(staff -> {
int age = staff.getAge();
int score = staff.getScore();
System.out.println("年龄:"+ age + "\t\t" + "KPI:" + score);
});
}
}
3、排序前后输出结果对比
排序前输出结果
年龄:5 KPI:102
年龄:8 KPI:103
年龄:4 KPI:104
年龄:4 KPI:105
排序后输出结果
年龄:8 KPI:103
年龄:5 KPI:102
年龄:4 KPI:105
年龄:4 KPI:104
年龄:5 KPI:102
年龄:8 KPI:103
年龄:4 KPI:104
年龄:4 KPI:105
排序后输出结果
年龄:8 KPI:103
年龄:5 KPI:102
年龄:4 KPI:105
年龄:4 KPI:104
通过上面的排序前后的输出结果看到,已经实现了之前的目的了。只要pojo类实现了 Comparable 接口,如果是 List<> 则使用 Collections.sort(); 方法进行排序。如果是Staff[]数组,则使用Arrays.sort()进行排序。
这里面说明一下:使用 Comparable 接口实现整体排序时,需要注意的是排序是以被实现的 compareTo () 方法中的参数为基准的。具体请各位读者自己测试。
二、Comparator接口的使用
1、需要进行整体排序的对象如下
package comparable_test;
/**
* 员工实体
* @author Scott
* @time 2017年9月9日
*/
public class Staff {
/** 员工年龄*/
private int age;
/** 员工KPI*/
private int score;
/**
* 构造函数
* @param age
* @param score
*/
public Staff(int age, int score) {
super();
this.age = age;
this.score = score;
}
//get set ...
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
2、使用 Comparator 接口对上面的 staff 进行整体排序
在使用 Comparator 接口实现整体排序时,需要实现自定义的比较器。
在使用 Collections.sort()或Arrays.sort() 进行排序时需要指定使用哪个比较器
package comparable_test;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* 测试类
* @author Scott
* @time 2017年9月11日
*/
public class TestSort {
/** Staff 列表*/
static List<Staff> staffInfos = new ArrayList<Staff>();
public static void main(String[] args) {
staffInfos.add(new Staff(5, 102));
staffInfos.add(new Staff(8, 103));
staffInfos.add(new Staff(4, 104));
staffInfos.add(new Staff(4, 105));
//排序前输出结果
System.out.println("排序前输出结果");
staffInfos.forEach(staff -> {
int age = staff.getAge();
int score = staff.getScore();
System.out.println("年龄:"+ age + "\t\t" + "KPI:" + score);
});
//使用 Comparator 构造自定义比较器
Comparator<Staff> comparaor = new Comparator<Staff>() {
@Override
public int compare(Staff o1, Staff o2) {
int i = 0;
if (o2.getAge() > o1.getAge()) {
i = 1;
} else if (o2.getAge() == o1.getAge()) {
if (o2.getScore() > o1.getScore()) {
i = 1;
} else if (o2.getScore() < o1.getScore()) {
i = -1;
}
} else if (o2.getAge() < o1.getAge()) {
i = -1;
}
return i;
}
};
//进行排序,第二个参数是指定使用的比较器
Collections.sort(staffInfos, comparaor);
//排序后输出结果
System.out.println("\n"+"排序后输出结果");
staffInfos.forEach(staff -> {
int age = staff.getAge();
int score = staff.getScore();
System.out.println("年龄:"+ age + "\t\t" + "KPI:" + score);
});
}
}
3、使用 Comparator 进行整体排序的输出结果
排序前输出结果
年龄:5 KPI:102
年龄:8 KPI:103
年龄:4 KPI:104
年龄:4 KPI:105
排序后输出结果
年龄:8 KPI:103
年龄:5 KPI:102
年龄:4 KPI:105
年龄:4 KPI:104
三、使用 Comparable 与 Comparator 两者的区别
从上面两个简答的使用例子中可以发现:
使用 Comparable 与 Comparator 两者的区别是:
* 1、使用 Comparable 在需要进行整体排序的类中 需要实现 Comparable 接口,实现接口中的 compareTo() 方法(比较器)。使用 Comparator 则不需要实现任何接口
* 2、使用 Comparator 需要自定义比较器,在排序时(使用Collections.sort()方法进行排序)需要指定比较器。而使用 Comparable 接口在排序时则不需要指定比较器
* 1、使用 Comparable 在需要进行整体排序的类中 需要实现 Comparable 接口,实现接口中的 compareTo() 方法(比较器)。使用 Comparator 则不需要实现任何接口
* 2、使用 Comparator 需要自定义比较器,在排序时(使用Collections.sort()方法进行排序)需要指定比较器。而使用 Comparable 接口在排序时则不需要指定比较器