在程序设计的过程中,经常会遇到需要进行排序的东西,对于一般的数字排序,有着各式各样的排序函数可以使用,但是他们经常是采取默认的方法进行排序的,当我么需要进行自定义的排序的时候,我们就需要自定义一个排序的方法,也就用到了对象比较器。
对象比较器可以自己定义比较的对象按照某一属性进行排序,实现该方法有两种途径:
- 实现Comparable接口
- 实现Comparator接口
对于这两种方法分别用两个实例代码举例:
1.实现Comparable接口:
下面是定义了一个Person类,实现了Comparable接口
package ComparableAndComparator;
/**
* Created by zhuxinquan on 16-6-1.
*/
public class Person implements Comparable<Person>{
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = 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;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Person o) {
//定义对象之间的比较规则
if(o == null){
throw new NullPointerException();
}
if(this.age < o.age){
return -1;
}else if(this.age > o.age){
return 1;
}
return 0;
}
}
实现了Comparable接口就要实现comparTo方法,该方法定义了对象之间的比较规则,举例来说,上面的person中的比较规则就是通过person对象的age属性来进行比较排序的。该排序方法返回1, -1或者0,分别表示大于,小于和等于,挡在外部使用排序算法对person对象进行排序的时候,默认调用的就是该方法,通过person对象的age属性进行排序。使用的操作如下:
import java.util.Arrays;
/**
* Created by zhuxinquan on 16-6-1.
*/
public class PersonSortDemo{
public static void main(String[] args) {
String[] names = {"hell", "erteri", "fedfs"};
Person[] persons = {
new Person("hell", 27), new Person("erteri", 29),
new Person("fedfs", 34)
};
Arrays.sort(names);
System.out.println(Arrays.toString(names));
Arrays.sort(persons);
System.out.println(Arrays.toString(persons));
}
}
上面的Arrays.sort方法是对数组进行排序,当数组是字符串的时候,默认采用字符串的ascii进行排序,实际上String类实现了Comparable接口,定义了下面的compareTo方法:
//String类中的compareTo方法
public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
int lim = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value;
int k = 0;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
return len1 - len2;
}
上面String类中的compareTo方法和person类中定义的方法都是通过自身和传进来的参数进行进行比较的。当我们直接调用Array.sort方法时,就会默认使用person类中的compareTo进行比较排序。
=======================================================
1.实现Comparator接口:
自定义一个比较器,然后实现Comparator接口,要进行排序时再讲比较器连通要进行排序的对象一块传入,即可按照自定义比较器中定义的方法进行比较排序。如下,定义了一个Person2Comparator类实现了Comparator接口:
package ComparableAndComparator;
import java.util.Comparator;
/**
* 自定义类比较器
* Created by zhuxinquan on 16-6-1.
*/
public class Person2Comparator implements Comparator<Person2>{
@Override
public int compare(Person2 o1, Person2 o2) {
if(o1 == null || o2 == null){
throw new NullPointerException();
}
if(o1.getAge() < o2.getAge()){
return -1;
}else if(o1.getAge() > o2.getAge()){
return 1;
}
return 0;
}
}
其中实现了compare方法,该方法和Comparable类中的compareTo方法一样,返回值分别是-1, 1, 0。与之不同的是,该方法一次性传入两个对象参数进行比较,而前面的传入一个与自身进行比较。使用如下:
Arrays.sort(persons2, new Person2Comparator());
直接传入要比较的对象和自定义的比较器即可。
为了方便使用(有可能所有的代码中只使用到一次比较器),我们可以直接声明一个内部类,直接实现Comparator类即可,如下:
Arrays.sort(persons, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
if(o1.getAge() > o2.getAge()){
return 1;
}
return 0;
}
});
这样直接在参数中声明了一个比较器类,实现了其中的方法。
========================================================