Java从入门到放弃(四)Comparable 和Comparator排序

       在Java中,要实现对象的排序,可以:实现Comparable或者Comparator接口。两者的区别是用Comparable一定要修改所排序对象的类的源码,而Comparator接口本身是一个比较器,可以通过实现这个接口定义对象的排序,也可以在排序的时候传入所定义的比较器来实现排序。

1、Comparable 类         

package java.lang;
import java.util.*;
public interface Comparable<T> {
    public int compareTo(T o);
}
    如上为Comparable的定义,只有一个compareTo方法,一个类实现了Comparable接口就可以实现排序。
    (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一样,让类直接实现,然后重写方法自定义排序逻辑,这里不做过多解释。如引用第三方的jar包,要让里面某个类实现排序,你可以修改源码实现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、总结

        Comparable是位于lang包下的,Comparator是位于util包下的,Comparable或者Comparator其实都是一样的,在使用场景上没有很大的区别,一般用Comparable就行,如果要在不修改源代码的情况下可以使用Comparator自定义比较器来实现排序,comparable相当于内部比较器。comparator相当于外部比较器。
        Collections.sort(list) 或者Arrays.sort(arr)不指定比较器,就会以内部实现的排序方法排序,其实Collections.sort(list)本身也是调用了Arrays.sort(arr)方法。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值