美文网首页
Comparable接口

Comparable接口

作者: 十一_2bef | 来源:发表于2018-06-08 11:19 被阅读0次

为何需要实现Comparable接口

我们知道Collections类中包含很多对实现Collection接口的容器各种操作的静态方法.
当然, 其中最长用的莫过于排序了(Collections.sort(List l).
下面是1个简单例子

public class Compare1{
    public static void f(){
        ArrayList arr = new ArrayList();
        arr.add(10);
        arr.add(23);
        arr.add(7);

        System.out.println(arr);

        Collections.sort(arr);
        
        System.out.println(arr);
    } 
}

逻辑很简单, 就是在1个list容器中添加3个int数值(注意实际被自动装箱成Interger对象).
正常输出容器元素一次, 利用Collections.sort()方法排序后, 再输出1次.

[java] [10, 23, 7]  
[java] [7, 10, 23]  

但是当List容器添加的元素对象是属于自己写的类时, 就可能出问题了.

例子:

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

class Student{
    private String name;
    private int ranking;

    public Student(String name, int ranking){
        this.name = name;
        this.ranking = ranking;
    } 

    public String toString(){
        return this.name + ":" + this.ranking;
    }
}

public class Compare2{
    public static void f(){
        ArrayList arr = new ArrayList();
        arr.add(new Student("Jack",10));
        arr.add(new Student("Bill",23));
        arr.add(new Student("Rudy",7));

        System.out.println(arr);
    } 
}

上面定义了1个Student类, 它只有两个成员, 名字和排名.
在f()方法内, 添加3个Student的对象到1个list容器中, 然后输出

 [Jack:10, Bill:23, Rudy:7] 

到此为止, 是没有问题的. 但是当对这个容器进行排序时就有问题了.

例如将上面的f()方法改成:

public class Compare2{
    public static void f(){
        ArrayList arr = new ArrayList();
        arr.add(new Student("Jack",10));
        arr.add(new Student("Bill",23));
        arr.add(new Student("Rudy",7));

        System.out.println(arr);
        Collections.sort(arr);
        System.out.println(arr);
    } 
}

编译时就会出错:

提示这个类Student没有实现Comparable接口.
原因也很简单, 因为Java不知道应该怎样为Student对象排序, 是应该按名字排序? 还是按ranking来排序?

为什么本文第1个例子就排序成功? 是因为Java本身提供的类Integer已经实现了Comparable接口. 也表明Integer这个类的对象是可以比较的.

而Student类的对象默认是不可以比较的. 除非它实现了Comparable接口.

总而言之, 如果你想1个类的对象支持比较(排序), 就必须实现Comparable接口.

Comparable接口简介.

Comparable 接口内部只有1个要重写的关键的方法.

就是

int compareTo(T o)

这个方法返回1个Int数值,

例如 i = x.compareTo(y)

如果i=0, 也表明对象x与y排位上是相等的

如果返回数值i>0 则意味者, x > y啦,

反之若i<0则 意味x < y

Comparable接口的实现及用法.

用回上面的例子, 我们修改Student类, 令其实现Comparable接口并重写compareTo方法.

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

class Student implements Comparable{
    private String name;
    private int ranking;

    public Student(String name, int ranking){
        this.name = name;
        this.ranking = ranking;
    } 

    public String toString(){
        return this.name + ":" + this.ranking;
    }

    public int compareTo(Object o){
        Student s = (Student)(o);
        return this.ranking - s.ranking;
    }
}

public class Compare2{
    public static void f(){
        ArrayList arr = new ArrayList();
        arr.add(new Student("Jack",10));
        arr.add(new Student("Bill",23));
        arr.add(new Student("Rudy",7));

        System.out.println(arr);
        Collections.sort(arr);
        System.out.println(arr);
    } 
}

注意重写的compareTo(Object o)方法内. 根据Student的ranking成员来比较的, 也就是说跟姓名无关了.

这时再编译执行, 就能见到List容器内的Student对象已经根据ranking来排序了.

输出:

[java] [Jack:10, Bill:23, Rudy:7]
[java] [Rudy:7, Jack:10, Bill:23]

一个例子

package neusoft;

/**
 * Created by ttc on 2018/11/1.
 */
public class MyComparable implements Comparable {
    String a;
    int aa;
    @Override
    public int compareTo(Object o) {
        System.out.println("compareTo");
       return this.aa - ((MyComparable)o).aa ;
//        return this.a.compareTo(((MyComparable)o).a);
    }

    public String getA() {
        return a;
    }

    public void setA(String a) {
        this.a = a;
    }

    public int getAa() {
        return aa;
    }

    public void setAa(int aa) {
        this.aa = aa;
    }

    @Override
    public String toString() {
        return "MyComparable{" +
                "a='" + a + '\'' +
                ", aa=" + aa +
                '}';
    }
}

//Comparable比较集合中的所有元素大小的例子
        List<MyComparable> list2Comparable = new ArrayList<>();
        MyComparable myComparable1 = new MyComparable();
        MyComparable myComparable2 = new MyComparable();
        MyComparable myComparable3 = new MyComparable();
        MyComparable myComparable4 = new MyComparable();
        myComparable1.setAa(20);
        myComparable2.setAa(35);
        myComparable3.setAa(10);
        myComparable4.setAa(18);
        list2Comparable.add(myComparable1);
        list2Comparable.add(myComparable2);
        list2Comparable.add(myComparable3);
        list2Comparable.add(myComparable4);

        for(MyComparable myComparable: list2Comparable)
        {
            System.out.println(myComparable);
        }

        Collections.sort(list2Comparable);
        System.out.println("------------------");
        for(MyComparable myComparable: list2Comparable)
        {
            System.out.println(myComparable);
        }

用Comparable进行比较,首先要在实现了comparable接口的类里面定义几个属性,要告诉方法,让他按照这个类的什么属性进行比较,如果是int型,没有现成的Comparable方法,如果是String型,有自己的比较方法,如上第一部分代码
在调用自己写的Comparable方法时,需要传入的是实现了Comparable接口的类,然后用Collections.sort(list2Comparable) 对该集合里面所有的类的对象按照规定的属性进行排序,再次输出,结果就是排序之后的结果,如下图所示

//排序前
MyComparable{a='null', aa=20}
MyComparable{a='null', aa=35}
MyComparable{a='null', aa=10}
MyComparable{a='null', aa=18}
//排序方法被调用的次数
compareTo
compareTo
compareTo
compareTo
compareTo
compareTo
------------------
//拍序后
MyComparable{a='null', aa=10}
MyComparable{a='null', aa=18}
MyComparable{a='null', aa=20}
MyComparable{a='null', aa=35}

相关文章

网友评论

      本文标题:Comparable接口

      本文链接:https://www.haomeiwen.com/subject/ywwosftx.html