Java中的对象,正常情况下,只能进行比较:== 或 != 。不能使用 > 或 < ,但是在开发场景中,我们需要对多个对象进行排序,言外之意,就需要比较对象的大小。
如何实现?使用两个接口中的任何一个:Comparable 或 Comparator
Comparable是一个对象本身就已经支持自比较所需要实现的接口,
如String、Integer自己就实现了Comparable接口,可完成比较大小操作。而自定义的类要在加入List容器中后才能实现排序,也可以实现Comparable接口。在使用Collection类的sort方法排序时若不指定Comparator,那就以自然顺序排序。
自然顺序就是实现Comparable接口设定的排序方式,因此我们需要在实现了Comparable接口的类中重写comparaTo(T o)方法。
实现了Comparable接口的类的对象的列表或数组可以通过Collections.sort或Array.sort进行自动排序。
补充:可以在泛型程序设计中给泛型变量继承Comparable从而使泛型变量可以利用a.compareTo(b)
来比较变量大小。
举例:
先写一个实现了Comparable接口的person类
public class Person implements Comparable<Person> {
String name;
int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Person() {
super();
}
@Override
public int compareTo(Person o) {
return this.age - o.age;
}
}
然后写测试类
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
Person p1 = new Person("zhangsan", 20);
Person p2 = new Person("lisi", 17);
Person p3 = new Person("wangwu", 27);
Person[] persons = {p1, p2, p3};
System.out.println("排序前");
for (Person person : persons) {
System.out.println(person.name + ":" + person.age);
}
//Arrays是数组工具类,Collections是集合工具类
Arrays.sort(persons);
System.out.println("排序后");
for (Person person : persons) {
System.out.println(person.name + ":" + person.age);
}
}
}
运行结果如下:
首先创建一个Person类,注意:这个类是没有实现comparable接口的
public class Person{
String name;
int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Person() {
super();
}
}
然后编写测试类:
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
Person p1 = new Person("zhangsan", 20);
Person p2 = new Person("lisi", 18);
Person p3 = new Person("wangwu", 26);
Person[] persons = {p1, p2, p3};
System.out.println("排序前");
for (Person person : persons) {
System.out.println(person.name + ":" + person.age);
}
//利用lambda表达式实现比较器
Arrays.sort(persons, (o1, o2) -> {
return o1.age - o2.age; //根据年龄升序排列
});
System.out.println("排序后");
for (Person person : persons) {
System.out.println(person.name + ":" + person.age);
}
}
运行结果如图:
当然也可以实现多属性排序:
重新编写一个测试类:
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
Person p1 = new Person("zhangsan", 20);
Person p2 = new Person("lisi", 18);
Person p3 = new Person("wangwu", 26);
Person p4 = new Person("lisi", 21);
Person[] persons = {p1, p2, p3, p4};
System.out.println("排序前");
for (Person person : persons) {
System.out.println(person.name + ":" + person.age);
}
//利用lambda表达式实现比较器
Arrays.sort(persons, (o1, o2) -> { //根据名字升序排序,若名字相同则根据年龄升序
if (o1.name.compareTo(o2.name) < 0) //排序
return -1;
else if (o1.name.compareTo(o2.name) > 0)
return 1;
else {
return o1.age - o2.age;
}
});
System.out.println("排序后");
for (Person person : persons) {
System.out.println(person.name + ":" + person.age);
}
}
}
运行结果如图:
Comparator被称为外部比较器,是因为如果我们需要对某个类(为了便于理解,我们这里称这个类为类A)进行排序(该类本身不支持排序),我们可以另外定义一个实现了Comparator接口的类(类B),来作为类A的“比较器”。这个“比较器”只需要实现Comparator接口即可。也就是说,我们可以通过“实现Comparator类来新建一个比较器”,然后通过该比较器对类进行排序。
注:类B即实现了Comparator接口的类,一定要实现compare(T o1, T o2)方法,该方法中就是我们自定义的对类A进行比较的规则 ;
int compare(T o1, T o2) 是“比较o1和o2的大小”。返回“负数”,意味着“o1比o2小”;返回“零”,意味着“o1等于o2”;返回“正数”,意味着“o1大于o2”。
public class Person {
String name;
int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Person() {
super();
}
}
然后创建一个person类的比较器PersonComparator类:
import java.util.Comparator;
public class PersonComparator implements Comparator<Person>{
@Override
public int compare(Person o1, Person o2) {
return o1.age - o2.age;
}
}
测试类:
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
Person p1 = new Person("zhangsan", 25);
Person p2 = new Person("lisi", 15);
Person p3 = new Person("wangwu", 35);
Person[] persons = {p1, p2, p3};
System.out.println("排序前");
for (Person person : persons) {
System.out.println(person.name + ":" + person.age);
}
Arrays.sort(persons, new PersonComparator());
System.out.println("排序后");
for (Person person : persons) {
System.out.println(person.name + ":" + person.age);
}
}
}
运行结果如图:
Comparable和Comparator接口都是实现集合中元素的比较、排序的,众所周知,诸如Integer,double等基本数据类型,java可以对他们进行比较,而对于类的比较,需要人工定义比较用到的字段比较逻辑。可以把Comparable理解为内部比较器,而Comparator是外部比较器。
Comparator接口允许在一个类中实现多种排序方法(只需要创建不同的比较器类即可),而Comparable接口只能在类中实现一种排序方法。
用Comparator接口来代替Comparable接口能更好地将数据类型的定义和两个该类型的对象应该如何比较的定义区分开来。
序的,众所周知,诸如Integer,double等基本数据类型,java可以对他们进行比较,而对于类的比较,需要人工定义比较用到的字段比较逻辑。可以把Comparable理解为内部比较器,而Comparator是外部比较器。
Comparator接口允许在一个类中实现多种排序方法(只需要创建不同的比较器类即可),而Comparable接口只能在类中实现一种排序方法。
用Comparator接口来代替Comparable接口能更好地将数据类型的定义和两个该类型的对象应该如何比较的定义区分开来。
比较两个对象(尤其是对象的字段有多个的时候)可以有多种标准,Comparator接口使我们能够在其中进行选择。