Comparable与Comparator比较

717 阅读1分钟

我的理解

Comparable更注重与集合内部固有的比较方法,如Integer,Double,Long等包装类型都有自带的比较方式;Comparator更注重人为安排的比较方式,在不改变原本类的情况下进行比较,而Comparable想要比较必须在构造类的时候就要写好比较情况

代码理解

假设我们只关注Student的分数和姓名,有Student类如下:

class Student implements Comparable<Student>{
    private Double score;
    private String name;

    public Student(Double score, String name) {
        this.score = score;
        this.name = name;
    }

    public Double getScore() {
        return score;
    }

    public void setScore(Double score) {
        this.score = score;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public int compareTo(Student o) {
        return this.score.compareTo(o.score);
    }

    @Override
    public String toString() {
        return "score=" + score + ", name='" + name +"'";
    }
}

测试Demo如下,将Student的容器进行升序排序:

public class CompareTest {
    public static void main(String[] args) {
        List<Student> list = new ArrayList<>();
        list.add(new Student(92.0,"张三"));
        list.add(new Student(95.0,"李四"));
        list.add(new Student(89.0,"王五"));
        list.add(new Student(77.0,"赵六"));
        list.add(new Student(99.0,"大马虎"));
        list.add(new Student(100.0,"小马虎"));
        Collections.sort(list);
        for (Student s :list) {
            System.out.println(s);
        }
    }
}

结果:

score=77.0, name='赵六'
score=89.0, name='王五'
score=92.0, name='张三'
score=95.0, name='李四'
score=99.0, name='大马虎'
score=100.0, name='小马虎'

如果我们想按姓名排序,而不修改原来Student的类结构代码,此时需要写另一个类(当然大家也可以利用lambda或者匿名类):

class CompareByName implements Comparator<Student>{
    public CompareByName() {
    }

    @Override
    public int compare(Student o1, Student o2) {
    	//String类也实现了Comparable接口
        return o1.getName().compareTo(o2.getName());
    }
}

测试Demo修改如下:

public class CompareTest {
    public static void main(String[] args) {
        List<Student> list = new ArrayList<>();
        list.add(new Student(92.0,"张三"));
        list.add(new Student(95.0,"李四"));
        list.add(new Student(89.0,"王五"));
        list.add(new Student(77.0,"赵六"));
        list.add(new Student(99.0,"大马虎"));
        list.add(new Student(100.0,"小马虎"));

        Collections.sort(list,new CompareByName());
        for (Student s :list) {
            System.out.println(s);
        }
    }
}

此时的结果就是按照姓名比较了(中文按照Unicode编码比较,英文按照ASCII码比较)

score=99.0, name='大马虎'
score=100.0, name='小马虎'
score=92.0, name='张三'
score=95.0, name='李四'
score=89.0, name='王五'
score=77.0, name='赵六'

谢谢大家耐心看完~