在Java中,要实现对象的排序,可以:实现Comparable或者Comparator接口。两者的区别是用Comparable一定要修改所排序对象的类的源码,而Comparator接口本身是一个比较器,可以通过实现这个接口定义对象的排序,也可以在排序的时候传入所定义的比较器来实现排序。
1、Comparable 类
package java.lang;
import java.util.*;
public interface Comparable<T> {
public int compareTo(T o);
}
(1)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的排序是根据字母的ASCII码表对应的数值来进行比较,所以a是大于A的,从代码可以看出是把String的字符数组依此比较,
若a.compareTo(b) <0,则a<b;若a.compareTo(b) =0,则a=b;若a.compareTo(b) >0,则a=b;
(2)举个栗子
public class ClassA implements Comparable<ClassA> {
private int age;
private String name;
public ClassA(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int compareTo(ClassA o) {
return this.age-o.age; //按照年龄升序排序
}
@Override
public String toString() {
return "ClassA{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
List<ClassA> list = new ArrayList<>();
list.add(new ClassA(17,"曹操"));
list.add(new ClassA(20,"刘备"));
list.add(new ClassA(16,"司马懿"));
list.add(new ClassA(26,"关羽"));
list.add(new ClassA(17,"孙权"));
list.add(new ClassA(18,"孙策"));
list.add(new ClassA(13,"诸葛亮"));
list.add(new ClassA(18,"周瑜"));
Collections.sort(list);
for(int i = 0,len = list.size(); i<len; i++) {
System.out.println(list.get(i));
}
输出为:
ClassA{age=13, name='诸葛亮'}
ClassA{age=16, name='司马懿'}
ClassA{age=17, name='曹操'}
ClassA{age=17, name='孙权'}
ClassA{age=18, name='孙策'}
ClassA{age=18, name='周瑜'}
ClassA{age=20, name='刘备'}
ClassA{age=26, name='关羽'}
2、Comparator
Comparator或者Comparable接口,使用Comparator可以在不修改源码的情况下实现排序,
public class ClassB{
private int age;
private String name;
private double height;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
}
public class Main {
public static void main(String[] args) {
List<ClassB> list = new ArrayList<>();
list.add(new ClassB(17,"曹操",177));
list.add(new ClassB(20,"刘备",176));
list.add(new ClassB(16,"司马懿",175));
list.add(new ClassB(26,"关羽",185));
list.add(new ClassB(17,"孙权",172));
list.add(new ClassB(18,"孙策",180));
list.add(new ClassB(13,"诸葛亮",175));
list.add(new ClassB(18,"周瑜",178));
MyComparator myComparator = new MyComparator();
Collections.sort(list,myComparator);
for(int i = 0,len = list.size();i<len;i++){
System.out.println(list.get(i));
}
}
//自定义比较器,按照年龄排序,如果年龄相等,比较身高
static class MyComparator implements Comparator<ClassB>{
@Override
public int compare(ClassB o1, ClassB o2) {
if(o1==o2){
return 0;
}
if(o1.getAge()==o2.getAge()){
if(o1.getHeight()==o2.getHeight()){
return 0;
}else{
return o1.getHeight() - o2.getHeight();
}
}else{
return o1.getAge()-o2.getAge();
}
}
}
}
输出
ClassB{age=13, name='诸葛亮', height=175}
ClassB{age=16, name='司马懿', height=175}
ClassB{age=17, name='孙权', height=172}
ClassB{age=17, name='曹操', height=177}
ClassB{age=18, name='周瑜', height=178}
ClassB{age=18, name='孙策', height=180}
ClassB{age=20, name='刘备', height=176}
ClassB{age=26, name='关羽', height=185}
3、总结
Comparator是位于util包下的,Comparable或者Comparator其实都是一样的,在使用场景上没有很大的区别,一般用Comparable就行,如果要在不修改源代码的情况下可以使用Comparator自定义比较器来实现排序,comparable相当于内部比较器。comparator相当于外部比较器。
Collections.sort(list)本身也是调用了Arrays.sort(arr)方法。