前言
最近在学习Java的基础语法,遇见了Comparator和Comparable两个用于比较的接口,特地记录一下,方便以后复习应用。本人作为新手,第一次写文章,如有错误欢迎指正。
一、Comparable
1.1 Comparable简介
Comparable为java.lang包下的排序接口。Arrars类中的sort方法承诺可以对对象数组进行排序,但需要满足下面的条件:对象所属的类必须实现Comparable接口。
Comparable接口的代码如下:
public interface Comparable {
int compareTo(Object other)
}
这说明,任何实现Comparable接口的类都需要包含compareTo方法,这个方法有一个Object参数,并且返回一个整数。
1.2 代码实例
首先定义一个Employee类实现Comparable接口,代码如下:
public class Employee implements Comparable<Employee>{
private String name;
private double salary;
public Employee(String name, double salary){
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;
}
/**
* Compares employees by salary
* @param o
* @return
*/
@Override
public int compareTo(Employee o) {
return Double.compare(salary, o.salary);
}
}
利用生成的类,在test类中直接使用Array.sort方法对类中元素进行排序(此时排序的对象是员工的薪水)。测试类代码如下:
public class ComparableTest {
public static void main(String[] args) {
var staff=new Employee[3];
staff[0]=new Employee("Harry Hacker",35000);
staff[1]=new Employee("Carl Cracker",75000);
staff[2]=new Employee("Tony Tester",30000);
Arrays.sort(staff);
for(Employee e:staff){
System.out.println("name="+e.getName()+",salary="+e.getSalary());
}
}
}
最终得到下面的结果:
name=Tony Tester,salary=30000.0
name=Harry Hacker,salary=35000.0
name=Carl Cracker,salary=75000.0
二、Comparator
2.1 Comparator简介
Comparator是比较接口,如果我们需要控制某个类的次序。而该类并没有实现Comparable接口,这是我们只需要定义一个比较器实现Comparator接口即可。
还有一种情况。例如,可以对一个字符串数组排序,因为String类实现了Comparable接口,而且String.compareTo方法可以按字典顺序比较字符串。而如果我们希望按长度递增的顺序对字符串进行排序,而不是按字典顺序进行排序。这时,我们不能让String类去用两种不同的方式来实现compareTo方法,更何况我们也不能去修改String类,这时我们就需要定义一个比较器去实现Comparator。
下面为Comparator接口的代码:
package java.util;
public interface Comparator<T>
{
int compare(T o1, T o2);
boolean equals(Object obj);
}
首先,定义一个Student类,不实现任何接口:
public class Students {
private String name;
private int no;
public Students() {
}
public Students(String name, int no) {
this.name = name;
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
@Override
public String toString() {
return "Students{" +
"name='" + name + '\'' +
", no=" + no +
'}';
}
}
下面为测试类:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
/**
* 用Comparator排序
*/
public class ComparatorTest {
public static void main(String[] args) {
ArrayList<Students> arrayList=new ArrayList<>();
arrayList.add(new Students("zhangsan",200112));
arrayList.add(new Students("lisi",200222));
arrayList.add(new Students("wangwu",389890));
arrayList.add(new Students("zhaoliu",467368));
Collections.sort(arrayList,new Comparator<Students>(){
@Override
public int compare(Students o1, Students o2) {
return o2.getNo()-o1.getNo();
}
});
for(Students s:arrayList){
System.out.println("学生的学号倒序:"+s.getNo());
}
}
}
这里利用了匿名内部类的方法,实现了一个比较器,完成了学生学号降序排列的功能。
其中,compare(int o1, int o2)方法 return o1 - o2 是升序,return o2 - o1 是降序。
最终实现结果如下:
学生的学号倒序:467368
学生的学号倒序:389890
学生的学号倒序:200222
学生的学号倒序:200112
总结
Comparable是排序接口,若一个类实现了Comparable接口,就意味着“该类支持排序”。而Comparator是比较器,我们若需要控制某个类的次序,可以建立一个“该类的比较器”来进行排序。
两种方法各有优劣, 用Comparable 简单, 只要实现Comparable 接口的对象直接就成为一个可以比较的对象,但是需要修改源代码。 用Comparator 的好处是不需要修改源代码, 而是另外实现一个比较器, 当某个自定义的对象需要作比较的时候,把比较器和对象一起传递过去就可以比大小了, 并且在Comparator 里面用户可以自己实现复杂的可以通用的逻辑,使其可以匹配一些比较简单的对象,那样就可以节省很多重复劳动了。