概要
Comparable和Comparator都是用于比较数据的大小的,实现Comparable接口需要重写compareTo方法,实现Comparator接口需要重写compare方法,这两个方法的返回值都是int,用int类型的值来确定比较结果,在Collections工具类中有一个排序方法sort,此方法可以只传一个集合,另一个重载版本是传入集合和比较器,前者默认使用的就是Comparable中的compareTo方法,后者使用的便是我们传入的比较器Comparator,java的很多类已经实现了Comparable接口,比如说String,Integer等类,而我们其实也是基于这些实现了Comparator或者Comparab接口的原生类来比较我们自己的类。
(1)Comparable
Comparable接口只有一个方法
package java.lang;
import java.util.*;
public interface Comparable<T> {
public int compareTo(T o);
}
调用此方法的对象,也就是this和o进行比较,若返回值大于0则this大于o,返回值等于0则是this等于o,返回值小于0则是this<o。
举例
1.定义一个Man.java类,实现Comparable接口,并且重写compareTo方法:默认比较的是当前Man类,通过age属性进行比较。
public class Man implements Comparable<Object> {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Man(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Man [name=" + name + ", age=" + age + "]";
}
@Override
public int compareTo(Object o) {
Man g = (Man) o;
return this.age - g.getAge();
}
}
2.定义测试类Test.java,定义一个ArrayList保存10个Man,打乱顺序后,查看输出结果
public static void main(String[] args) {
List<Man> list = new ArrayList<>(10);
Man man;
for (int i = 1; i <= 10; i++) {
man = new Man("man" + i, i);
list.add(man);
}
System.out.println("排序前");
list.stream().forEach(System.out::println);
System.out.println("排序后");
Collections.sort(list);
list.stream().forEach(System.out::println);
}
运行结果
排序前
Man [name=man1, age=1]
Man [name=man2, age=2]
Man [name=man3, age=3]
Man [name=man4, age=4]
Man [name=man5, age=5]
Man [name=man6, age=6]
Man [name=man7, age=7]
Man [name=man8, age=8]
Man [name=man9, age=9]
Man [name=man10, age=10]
排序后
Man [name=man10, age=10]
Man [name=man9, age=9]
Man [name=man8, age=8]
Man [name=man7, age=7]
Man [name=man6, age=6]
Man [name=man5, age=5]
Man [name=man4, age=4]
Man [name=man3, age=3]
Man [name=man2, age=2]
Man [name=man1, age=1]
(2)Comparator
Comparator接口中方法很多,但是我们只需要实现一个,也是最重要的一个compare,也许有的人会好奇为什么接口中的方法可以不用实现,因为这是JDK8以后的新特性,在接口中用default修饰的方法可以有方法体,在实现接口的时候可以不用重写,可以类比抽象类。
package java.util;
public interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj);
}
举例
1.定义一个Man类
package ThreadsExecuteSequentially;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class Man implements Comparator<Man> {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Man(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Man [name=" + name + ", age=" + age + "]";
}
@Override
public int compare(Man o1, Man o2) {
return o1.age - o2.age;
}
}
2.定义测试类Test.java,定义一个ArrayList保存10个Man,查看输出结果
public static void main(String[] args) {
List<Man> list = new ArrayList<>(10);
Man man;
for (int i = 1; i <= 10; i++) {
man = new Man("man" + i, i);
list.add(man);
}
list.stream().forEach(System.out::println);
}
输出结果
Man [name=man1, age=1]
Man [name=man2, age=2]
Man [name=man3, age=3]
Man [name=man4, age=4]
Man [name=man5, age=5]
Man [name=man6, age=6]
Man [name=man7, age=7]
Man [name=man8, age=8]
Man [name=man9, age=9]
Man [name=man10, age=10]