若一个类实现了Comparable接口,就意味着该类支持排序。实现了 Comparable接口的类的对象的列表或数组可以通过Collections.sort或Arrays.sort进行自动排序。
此外,实现此接口的对象可以用作有序映射中的键或有序集合中的集合,无需指定比较器。
此接口只有一个方法compare,比较此对象与指定对象的顺序,如果该对象小于、等于或大于指定 对象,则分别返回负整数、零或正整数。
Comparable 接口仅仅只包括一个函数,如下
package java.lang;
import java.util.*;
public interface Comparable {
//必须实现的抽象方法
public int compareTo(T o);
}
说明:根据这个方法的返回值来判断
大于0:说明前一个比后一个大
小于0:说明前一个小于后一个
等于0:说明这两个一样大
示例:
这里有一个员工类Employee1,我们需要堆员工实体对员工的工资进行排序,所以这里用实现Comparable接口,重写compareTo方法
import java.util.Arrays;
public class Employee1 implements Comparable<Employee1>{
private String name;
private double salary;
public Employee1(String name , double salary){
this.name = name;
this.salary = salary;
}
public Employee1(String name , double salary, int height){
this.name = name;
this.salary = salary;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
public void raiseSalary(double byPercent) {
double raise = salary * byPercent / 100;
salary += raise;
}
@Override
public String toString() {
return "Employee1{" +
"name='" + name + '\'' +
", salary=" + salary +
'}';
}
/**
* 重写排序规则:
* 定义我们的排序规则,用salary来排序
* @param other
* @return
*/
@Override
public int compareTo(Employee1 other) {
return Double.compare(salary,other.salary);
}
}
此时:我们重写了compareTo方法,可以看出是用成员变量salary进行了比较,当前一个对象小于后一个对象时,返回小于0,反之大于0,等于则返回0.
测试类:
public static void main(String[] args) {
Employee1[] temp=new Employee1[4];
temp[0]=new Employee1("张三",150);
temp[1]=new Employee1("李四",120);
temp[2]=new Employee1("王五",135);
temp[3]=new Employee1("小花",80);
Arrays.sort(temp);
for (Employee1 employee1 : temp) {
System.out.println(employee1.toString());
}
}
输出结果:
总结:
此时因为我们已经重写了compareTo方法,这里我们用实现Comparable的方法进行了对象的排序。
背景:
我们若需要控制某个类的次序,而该类本身不支持排序(即没有实现Comparable接口);那么,我们可以建立一个“该类的比较器”来进行排序。这个“比较器”只需要实现Comparator接口即可。也就是说,我们可以通过“实现Comparator类来新建一个比较器”,然后通过该比较器对类进行排序。
特别说明
若一个类要实现Comparator接口:它一定要实现compareTo(T o1, T o2) 函数,但可以不实现 equals(Object obj) 函数。
为什么可以不实现 equals(Object obj) 函数呢? 因为任何类,默认都是已经实现了equals(Object obj)的。 Java中的一切类都是继承于java.lang.Object,在Object.java中实现了equals(Object obj)函数;所以,其它所有的类也相当于都实现了该函数。
package java.util;
public interface Comparator {
int compare(T o1, T o2);
boolean equals(Object obj);
}
int compare()方法
返回值为:
小于0–>前一个对象小于后一个对象
大于0–>前一个对象大于后一个对象
等于0–>前一个对象等于后一个对象
背景
此时,我们在Employee1类的基础上,我们再添加一个升高,但是这个类的依旧实现了Comparable接口,重写了compareTo方法,并且这个方法按照工资薪水排序,此时我们如何能都不改变代码的前提下,重新对升高排序呢?
此时就引入了Comparator接口,我们实现这个接口的int compare方法,具体如下
public class Employee implements Comparable<Employee>{
private String name;
private double salary;
private int height;
public Employee(String name , double salary){
this.name = name;
this.salary = salary;
}
public Employee(String name , double salary, int height){
this.name = name;
this.salary = salary;
this.height= height;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getSalary() {
return salary;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public void setSalary(Double salary) {
this.salary = salary;
}
public void raiseSalary(double byPercent) {
double raise = salary * byPercent / 100;
salary += raise;
}
/**
* 重写排序规则:
* 定义我们的排序规则,用salary来排序
* @param other
* @return
*/
@Override
public int compareTo(Employee other) {
return Double.compare(salary,other.salary);
}
}
编写测试类:
public class EmployeeSortTest {
public static void main (String[] args) {
Employee[] staff = new Employee[4];
staff[0] = new Employee ("张三" , 35000,175) ;
staff[1] = new Employee ("李四" , 75000,165);
staff[2] = new Employee ("王五" , 38000,180) ;
staff[3] = new Employee ("小六" , 23000,153) ;
//核心排序代码,对升高进行排序
Arrays.sort(staff, Comparator.comparingInt(Employee::getHeight));
//遍历数组结果
for (Employee e : staff){
System.out.println("name=" + e.getName() + " ,salary=" + e.getSalary()+" ,height="+e.getHeight());
}
}
}
对于核心排序代码,我们也可以用lambda表达式来编写:
Arrays.sort(staff,((o1, o2) -> {
if(o1.getHeight()==o2.getHeight()){
return 0;
}
return o1.getHeight()-o2.getHeight();
})) ;
原因;
从Arrays.sort()源码的角度分析,sort方法接收的参数类型,一个为数组类型,一个为Comparator对象,因为Comparator为接口所以不能实例化,但是我们可以用多态来指向它,我们可以声明Comparator的实现类对象指向这个接口,此时就可以调用这个接口。
当我们用lambda表达式时,也是创建了这个Comparator接口的具体实现方法,所以两者都可以进行排序,看读者的自己。
输出结果:
此时我们的这个数组对象就已经按照升高排序,实现需求。
Comparable是排序接口;若一个类实现了Comparable接口,就意味着“该类支持排序”。
而Comparator是比较器;我们若需要控制某个类的次序,可以建立一个“该类的比较器”来进行排序。
的自己。