Java中Comparable和Comparator

Java中对象排序的两种方式:

1.实现Comparable接口

2.实现Comparator接口

其中Comparable在java.lang包下,Comparator在java.util包下,这两种方式具体实现方法和应用场景如下:

1.Collections的sort()方法要求被排序对象必须实现Comparable接口并重写其中的compareTo()方法

package test;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

class Person1 implements Comparable<Person1>{
    String name;
    int age;
    public Person1(String name,int age) {
        this.age = age;
        this.name = name;
    }
    @Override
    public String toString(){
        return name + age;
    }
    @Override
    public int compareTo(Person1 other){
        if(this.name != other.name) return this.name.compareTo(other.name);
        else return this.age - other.age;
    }
}
public class ComparableTest {
    public static void main(String[] args) {
        List<Person1> persons = Arrays.asList(
            new Person1("tom", 25),
            new Person1("frank", 27),
            new Person1("tom", 20)
        ) ;
        Collections.sort(persons);
        System.out.println(persons);
    }
}

 

2.有了Comparable为什么还要有Comparator呢?

 

上面的代码中Person1对象操作了Comparable接口,但如果你的对象无法操作Comparable呢?也许你拿不到原始码,也许你不能修改原始码。举个例子,我们现在对String排序,String本身有操作Comparable,但默认的String排序是按照字典序从小到大,今天你想让排序结果反过来从大到小怎么办?修改String.java里的comparaTo()方法?这方法明显不可行,就算你修改后重新编译为String.class放回rt.jar中,也只有你的JRE能用,这已经不是标准API了。继承String重新定义compareTo()方法?也不可能,因为String声明为final,不能被继承。

Collections的sort()方法有另一个重载版本,可接受Comparator接口的操作对象(通常称作比较器),如果使用这个版本,排序方式将根据Comparator的compare()定义来决定。我们这里还是按照Person类的排序。

package test;

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

class Person2{
    String name;
    int age;
    public Person2(String name,int age) {
        this.age = age;
        this.name = name;
    }
    @Override
    public String toString(){
        return name + age;
    }
}
class PersonComparator implements Comparator<Person2>{
    @Override
    public int compare(Person2 o1, Person2 o2) {
        if(o1.name != o2.name) return o1.name.compareTo(o2.name);
        else return o1.age - o2.age;
    }	
}
public class ComparatorTest {
    public static void main(String[] args) {
        List<Person2> persons = Arrays.asList(
            new Person2("tom", 25),
            new Person2("frank", 27),
            new Person2("tom", 20)
        ) ;
        Collections.sort(persons, new PersonComparator());
        System.out.println(persons);
    }
}

从代码中可以看出我们唯一需要做的就是增加一个名为PersonComparator的比较器,把上面代码中Person1中的比较规则放进去,然后在Collections.sort中创建比较器实例,这样可以在不能操作对象源代码的情况下实现对象排序。

JDK8在List上增加了sort()方法,可接受Comparator实例来指定排序方式,因此以上代码可以通过Lambda表达式简化为

package test;

import java.util.Arrays;
import java.util.List;

class Person3{
    String name;
    int age;
    public Person3(String name,int age) {
        this.age = age;
        this.name = name;
    }
    @Override
    public String toString(){
        return name + age;
    }
}
public class LambdaComparator {
    public static void main(String[] args) {
        List<Person3> persons = Arrays.asList(
            new Person3("tom", 25),
            new Person3("frank", 27),
            new Person3("tom", 20)
        ) ;
        persons.sort((o1,o2) -> {
            if(o1.name != o2.name) return o1.name.compareTo(o2.name);
            else return o1.age - o2.age;
        });
        System.out.println(persons);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值