进行自定义对象的比较时,因为包含很多属性,一般根据这些属性对自定义对自定义对象进行比较,所以java中要比较对象的大小或者要对对象的集合进行排序,需要比较这些对象的属性的大小来确定它们之间的大小关系。java中比较常用比较就是Comparable接口和Comparator接口。
一.Comparable接口
该接口对实现它的每个类的对象强加一个整体排序。这个排序称为类的自然排序。类的CompareTo方法被称为其自然比较方法。
Collections.sort(和Arrays.sort)可以自动对实现此接口的对象进行列表(和数组)排序,实现此接口的对象可以用作有序映射表中(Map)或作为有序集合中(Set)中的元素,而不需要指定一个比较器(comparator)。几乎所有实现Comparable的java核心类都具有equals一致的自然排序,一个例外是java.math.BigDecimal,其自然排序等于BigDecimal具有相同值和不同精度的对象。
实现的方法:int CompareTo(T o)
比较此对象与指定的对象进行比较以进行排序,返回一个负整数,零或正整数。
- 该方法返回<0 this比较小
- 该方法返回==0 相等
- 该方法返回>0 o比较小
异常:
- NullPointerException 如果指定的对象为空
- ClassCastException 如果指定的对象的类型阻止它与该对象进行比较。
/**
* 因为要实现对Person对象的排序,所以要在Person类中要实现Comparable接口,
* 实现compareTo()方法
*/
public class Person implements Comparable<Person> {
public String name;
public int age;
public int rank;
@Override
public int compareTo(Person o) {
return this.age-o.age;
}
@Override
//这里只比较了年龄
public String toString() {
return "Person{" +
"age=" + age +
'}';
}
}
//测试类
import java.util.*;
public class ComparableSort {
public static void main(String[] args) {
Person[] people=new Person[10];
Random random=new Random(20190922);
for(int i=0;i<people.length;i++){
people[i]=new Person();
people[i].age=random.nextInt(60);
}
System.out.println(Arrays.toString(people));
Arrays.sort(people);
System.out.println(Arrays.toString(people));
}
}
运行结果:
二.Comparator 接口
需要定义一个比较器类,实现Comparator接口
比较功能,对一些对象的集合暑假了一个整体排序。可以将比较器传递给排序方法(Collections.sort或Arrays.sort),以便对排序顺序进行精确控制,比较器还可以用来控制某些数据结构,如顺序sorted sets 或sorted maps。
通过比较c上的一组元素s确定的顺序对被认为是是与equals一致当且仅当c.compare(e1,e2)==0具有用于e1和e2相同布尔值e1.equals(e2);
实现的方法:
- int compare(T o1,T o2)
比较两个参数的顺序,返回负整数,零或正整数因为第一个参数小于,等于或大于第二个参数。
参数:
- o1:要比较的第一个对象
- o2:要比较的第二个对象
结果:
- 结果返回>0 o1>o2
- 结果返回==0 o1==o2
- 结果返回<0 01<o2
异常:
- NullPointerException:如果参数为空,并且此比较器不允许空参数
- ClassCastExceptin:如果参数类型阻止他们被比较器进行比较
import java.util.*;
//具体的比较类(比较器),实现Comparator接口
public class PersonRankComparator implements Comparator<PersonComparator> {
@Override
public int compare(PersonComparator o1, PersonComparator o2) {
return (o1.age-o2.age);
}
}
//需要进行比较的类
public class PersonComparator {
public String name;
public int age;
public int rank;
@Override
public String toString() {
return "PersonComparator{" +
"age=" + age +
'}';
}
}
//测试类
import java.util.*;
public class ComparatorTest {
public static void main(String[] args) {
PersonComparator[] people=new PersonComparator[5];
Random random=new Random(20190922);
for(int i=0;i<people.length;i++){
people[i]=new PersonComparator();
people[i].age=random.nextInt(60);
}
System.out.println(Arrays.toString(people));
PersonRankComparator personRankComparator=new PersonRankComparator();
Arrays.sort(people,personRankComparator);
System.out.println(Arrays.toString(people));
}
}
运行截图:
三.比较
- 1.Comparable 接口将比较代码嵌入需要比较的类的自身代码中,而Comparator接口在一个独立的类中实现比较;
- 2.Comparable位于包java.lang下,Comparator位于包java.util下
- 3.如果前期类的设计没有考虑到类的Compare问题而没有实现Comparable接口,后期可以通过Comparator接口来实现算法进行排序;
- 4.Comparable接口强制进行自然排序,而Comparator接口不强制进行自然排序,可以指定排序顺序。
注:参考jdk+api+1.8.ChM文档