Comparable和Comparator的区别

Posted qlqwjy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Comparable和Comparator的区别相关的知识,希望对你有一定的参考价值。

  

  在Java集合的学习中,我们明白了:

    看到tree,可以按顺序进行排列,就要想到两个接口。Comparable(集合中元素实现这个接口,元素自身具备可比性),Comparator(比较器,传入容器构造方法中,容器具备可比性)。

那么Comparable和Comparator有什么区别呢?

1.  Comparable---接口(集合中元素实现此接口,元素具有可比性)

  Comparable可以认为是一个内比较器,实现了Comparable接口的类有一个特点,就是这些类是可以和自己比较的,至于具体和另一个实现了Comparable接口的类如何比较,则依赖compareTo方法的实现,compareTo方法也被称为自然比较方法。如果开发者add进入一个Collection的对象想要Collections的sort方法帮你自动进行排序的话,那么这个对象必须实现Comparable接口。compareTo(Object o)方法的返回值是int,且此方法只有一个参数,返回值有三种情况:

1、返回正整数

2、返回0

3、返回负整数

  可以这么理解:返回1表示当前元素排在与之对比的元素后面,返回-1表示当前元素排在与之对比的元素前面,返回0表示不排序(按其原顺序排列)。(其实并不是1,-1,0;只要是正数负数和0就可以进行区分)。

  元素自身可以理解为基准,而参数上的obj可以理解为与之对比的元素。

 

1.比如我们想比较人的时候按年龄倒序排列

  思路:实现上面接口,如果与之对比的元素年龄比他大,排在他前面(返回负数),否则排在他后面(返回正数)。

例如:

public class Person implements Comparable<Person> {

    private int age;
    private String 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(Person o) {
        if(this.age > o.getAge()){//返回负数表示比他大的排在他前面
            return -1;
        }
        if(this.age < o.getAge()){//返回整数表示比他小的排在他后面
            return 1;
        }
        return 0;
    }

    public Person(int age, String name) {
        super();
        this.age = age;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person [age=" + age + ", name=" + name + "]";
    }
    

}

 

 

测试:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


public class Test1 {
    public static void main(String[] args) {
        List<Person> list = new ArrayList<>();
        list.add(new Person(20, "张三"));
        list.add(new Person(22, "李四"));
        list.add(new Person(19, "王五"));
        list.add(new Person(19, "张是"));
        list.add(new Person(17, "开发"));
        list.add(new Person(29, "看"));
        
        Collections.sort(list);
        for(Person p : list){
            System.out.println(p);
        }
    }
}

 

 

结果:

Person [age=29, name=看]
Person [age=22, name=李四]
Person [age=20, name=张三]
Person [age=19, name=王五]
Person [age=19, name=张是]
Person [age=17, name=开发]

 

2.按照上面的思路我们写一个按年龄正序排列

修改上面的compareTo方法:

    @Override
    public int compareTo(Person o) {
        if(this.age > o.getAge()){//返回正数表示比他大的排在他后面
            return 10;
        }
        if(this.age < o.getAge()){//返回负数表示比他小的排在他前面
            return -1;
        }
        return 0;
    }

 

 

测试代码还是上面代码,查看结果:

Person [age=17, name=开发]
Person [age=19, name=王五]
Person [age=19, name=张是]
Person [age=20, name=张三]
Person [age=22, name=李四]
Person [age=29, name=看]

 

2.  Comparator---接口(可以理解为比较器,给集合传递比较器集合具有可比性)

  Comparator相当于外部比较器,其作为参数传给具有可比性的集合,使集合具有可比性。比如:      TreeSet ts = new TreeSet(new MyComparator());   比较器需要重写compareTo(Object o1,Object o2)方法,返回值也是下面三个值:

1、返回正整数

2、返回0

3、返回负整数

  可以这么理解:返回1表示当前元素排在与之对比的元素后面,返回-1表示当前元素排在与之对比的元素前面,返回0表示不排序(按其原顺序排列)。(其实并不是1,-1,0;只要是正数负数和0就可以进行区分)

   compareTo(Object o1,Object o2)方法的第一个参数可以理解为基准,而参数上的第二个参数可以理解为与之对比的元素。

1.比如我们想比较人的时候按年龄倒序排列

public class Person{

    private int age;
    private String 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;
    }

    public Person(int age, String name) {
        super();
        this.age = age;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person [age=" + age + ", name=" + name + "]";
    }
    

}

 

 

比较器类:(可以理解为第一个参数是基准,第二个参数是与之对比的元素,返回-1表示基准排在与之对比元素前面,返回1表示基准在与之对比的元素后面)

import java.util.Comparator;

public class PersonComparator implements Comparator<Person> {

    /**
     * 第一个参数可以理解为基准,第二个是与之比较多元素 。返回负数表示排在其前面,返回正数表示排在其后面
     */
    @Override
    public int compare(Person o1, Person o2) {
        if (o1.getAge() > o2.getAge()) {// 返回正数表示比他大的排在他后面
            return -1;
        }
        if (o1.getAge() < o2.getAge()) {
            return 1;
        }
        return 0;
    }

}

 

 

测试代码:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


public class Test1 {
    public static void main(String[] args) {
        List<Person> list = new ArrayList<>();
        list.add(new Person(20, "张三"));
        list.add(new Person(22, "李四"));
        list.add(new Person(19, "王五"));
        list.add(new Person(19, "张是"));
        list.add(new Person(17, "开发"));
        list.add(new Person(29, "看"));
        
        Collections.sort(list,new PersonComparator());
        for(Person p : list){
            System.out.println(p);
        }
    }
}

 

 

结果:

Person [age=29, name=看]
Person [age=22, name=李四]
Person [age=20, name=张三]
Person [age=19, name=王五]
Person [age=19, name=张是]
Person [age=17, name=开发]

 

 

2.写一个正序的比较器就简单了

import java.util.Comparator;

public class PersonComparator implements Comparator<Person> {

    /**
     * 第一个参数可以理解为基准,第二个是与之比较多元素 。返回负数表示排在其前面,返回正数表示排在其后面
     */
    @Override
    public int compare(Person o1, Person o2) {
        if (o1.getAge() > o2.getAge()) {
            return 10;
        }
        if (o1.getAge() < o2.getAge()) {
            return -10;
        }
        return 0;
    }

}

 

以上是关于Comparable和Comparator的区别的主要内容,如果未能解决你的问题,请参考以下文章

Java中Comparable与Comparator的区别

Java中Comparable与Comparator的区别

java中Comparable和Comparator区别和总结

Comparable和Comparator的区别

Java中的comparable接口和Comparator接口的区别

Java中Comparable和Comparator接口区别分析