Comparable接口与Comparator接口

Comparable接口与Comparator接口
1.Comparable(内部排序接口)简介:
若一个类实现了Comparable接口,就意味着“该类支持排序”。既然实现Comparable接口的类支持排序,假设现在存在“实现Comparable接口的类的对象的List列表(或数组)”,则该List列表(或数组)可以通过Collections.sort(或Arrays.sort)进行排序。
此外,“实现Comparable接口的类的对象”可以用做“有序映射TreeMap”中的键或“有序集合TreeSet”中的元素,而不需要指定比较器。
Comparable定义:
Comparable接口仅仅包括一个函数,它的定义如下:
public interface Comparable{
public int compareTo(T o);
}
关于返回值
可以看出CompareTo方法返回一个int值,该值有三种返回值:
1.返回负数:表示当前对象小于比较对象,
2.返回0:表示当前对象等于目标对象,
3.返回正数:表示当前对象大于目标对象。
2.Comparator(外部排序接口)简介:
Comparator是比较器接口。
我们若需要控制某个类的次序,而该类本身不支持排序(即没有实现Comparable接口);那么,我们可以建立一个“该类的比较器”来进行排序。这个“比较器”只需要实现Coparator接口即可。
也就是说,我们可以通过“实现Comparator类来新建一个比较器”,然后通过该比较器对垒进行排序。
Comparator定义:
Comparator接口仅仅只包括两个函数,它的定义如下:
public interface Comparator{
int compare(T o1,T o2);
boolean equals(Object obj);
}
int compare(T o1,T o2);是比较o1和o2的大小。返回负数,意味着o1比o2小;返回0,意味着o1等于o2;返回正数,意味着意味着o1比o2。
3.Comparator和Comparable比较
Comparable是排序接口;若一个类实现了Comparable接口,就意味着“该类支持排序”。而Comparator是比较器;我们若需要控制某个类的次序,可以建立一个“该类的比较器”来进行排序。
我们不难发现:Comparable相当于“内部比较器”,而Comparator相当于“外部比较器”。
4.说明:

  1. String已经实现过Comparable;
    Integer已经实现过Comparable。
  2. 对象无法带有顺序,不能使用<,=,>,如何让解决这个问题呢?
    两种办法:
    2.1自然顺序: 类实现Comaprable接口
    使用方式:
    p.comapreTo(q);
    2.2非自然顺序:定义一个比较器(实现Comaprator类)
    使用方式:
    Comparator 比较器=new …;
    比较器.compare(p,q);
  3. 泛型接口:
    3.1 Comaprable<>
    class Person implements Comparable
    //1.定义了Person类
    //2.Person具备自然顺序
    //3.Person类的自然顺序是需要和一个Person比较
    3.2 Comparator<>
    class PersonHeightComparator implements Comparator
    //1.定义了一个比较器类,名字是PersonHeightComparator
    //2.这个比较器负责Person类型的比较
  4. 有Comparable为何还要引入Comparator?
    有些天生没有自然顺序,或者自然顺序比满足我们的需要,所以需要引入比较器来做比较。
    示例1:
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

class Person {
	private String name;
	private Integer age;

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

	public String toString() {
		return "Person{" + "name='" + name + '\'' + ",age=" + age + '}';
	}

	public String getName() {
		return name;
	}

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

	public Integer getAge() {
		return age;
	}

	public void setAge() {
		this.age = age;
	}
}

class AscAgeComparator implements Comparator<Person> {
	public int compare(Person o1, Person o2) {
		return o1.getAge() - o2.getAge();
	}
}

class DescAgeComparator implements Comparator<Person> {
	public int compare(Person o1, Person o2) {
		return o2.getAge() - o1.getAge();
	}
}

public class TestDemo {
	public static void main(String[] args) {
		Set<Person> set = new TreeSet<>(new AscAgeComparator());
		set.add(new Person("张三", 20));
		set.add(new Person("李四", 18));
		System.out.println(set);
		Set<Person> set2 = new TreeSet<>(new DescAgeComparator());
		set2.add(new Person("张三", 20));
		set2.add(new Person("李四", 18));
		System.out.println(set2);
	}
}

运行结果:
在这里插入图片描述
示例2:


import java.util.Comparator;
class PersonHeightComparator implements Comparator<Person>{
    @Override
    public int compare(Person o1, Person o2) {
        return (int)(o1.height-o2.height);
    }
}
class PersonNameComparator implements Comparator<Person>{

    @Override
    //把Person1的name取出来,并用Person1的自然顺序为比较顺序
    public int compare(Person o1, Person o2) {
        return o1.name.compareTo(o2.name);
    }
}
public class Person implements Comparable<Person>{
    public String name;
    public int age;
    public double height;
    public int weight;
    public int level;
    public int gender;

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

    @Override
    public int compareTo(Person o) {
        return age-o.age;
        /*
        if(age<o.age){
            return -1;
        }else if(age==o.age){
            return 0;
        }else if(age>o.age){
            return 1;
        }
        */
    }
    
//设计一个复杂比较器,比较顺序依次为身高、体重、姓名、年龄
    class ComplexComparator implements Comparator<Person>{
        @Override
        public int compare(Person o1, Person o2) {
            if(o1.height<o2.height){
                return -1;
            }else if(o1.height>o2.height){
                return 1;
            }
            if(o1.weight<o2.weight){
                return -1;
            }else if(o1.weight>o2.weight){
                return 1;
            }
            int n=o1.name.compareTo(o2.name);
            if(n!=0){
                return n;
            }
            return o1.age-o2.age;
        }
    }
    
    public static void main(String[] args) {
        Person p=new Person("James",18,185.0);
        Person q=new Person("Tom",20,180.2);
        //按照年龄比较
        System.out.println("按照年龄比较:");
        int a=p.compareTo(q);
        if(a<0){
            System.out.println("p小于q");
        }else if(a==0){
            System.out.println("p等于q");
        }else{
            System.out.println("p大于q");
        }

        Comparator<Person> comparator=new PersonNameComparator();
        //按照姓名比较
        System.out.println("按照姓名比较:");
        int n=comparator.compare(p,q);
        if(n<0){
            System.out.println("p小于q");
        }else if(n==0){
            System.out.println("p等于q");
        }else{
            System.out.println("p大于q");
        }

        comparator=new PersonHeightComparator();
        //基于身高的比较
        System.out.println("按照身高比较:");
        int h=comparator.compare(p,q);
        if(h<0){
            System.out.println("p小于q");
        }else if(h==0){
            System.out.println("p等于q");
        }else{
            System.out.println("p大于q");
        }

        //额外的验证用例:String和Integer已经实现过Comparable
        System.out.println("额外的验证用例:体现String已经实现过Comparable:");
        System.out.println("abc".compareTo("bbc"));
        System.out.println("abc".compareTo("abcd"));
    }
}

运行结果:
在这里插入图片描述
示例3.1:下例的前奏


import java.util.Comparator;

public class Student {
    static class Sort{
        static void insertSort(Student[] students){
            for(int i=1;i<students.length;i++){
                Student k=students[i];
                int j=i-1;
                for(; j>0&&((Comparable<Student>)students[j]).compareTo(k)>0; j--){
                    students[j+1]=students[j];
                }
                students[j+1]=k;
            }
        }

        static void insertSort(Student[] students,Comparator<Student> cmp){
            for(int i=1;i<students.length;i++){
                Student k=students[i];
                int j=i-1;
                for(; j>0&&cmp.compare(students[j],k)>0; j--){
                    students[j+1]=students[j];
                }
                students[j+1]=k;
            }
        }
    }

    public String sn;
    public String name;
    public int age;

    public static class Cmp implements Comparator<Student>{
        @Override
        public int compare(Student o1, Student o2) {
            return 0;
        }
    }
    
    public static void main(String[] args) {
        Student[] students={new Student()};
        Sort.insertSort(students,new Cmp());
    }
}

示例3.2:和图书排序有关的联系


import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

public class Book implements Comparable<Book>{
    String ISBN;
    String title;
    String author;
    int price;
    int sales;
    int comments;

    public Book(String ISBN, String title, String author, int price, int sales, int comments) {
        this.ISBN = ISBN;
        this.title = title;
        this.author = author;
        this.price = price;
        this.sales = sales;
        this.comments = comments;
    }

    @Override
    public int compareTo(Book o) {
        return 0;
    }

    @Override
    public String toString() {
        return "Book{" +
                "ISBN='" + ISBN + '\'' +
                ", title='" + title + '\'' +
                ", author='" + author + '\'' +
                ", price=" + price +
                ", sales=" + sales +
                ", comments=" + comments +
                '}';
    }
    
    static class Sort {
        public static void sort(List<Book> books) {
            for (int i = 1; i < books.size(); i++) {
                Book book = books.get(i);
                int j = i - 1;
                for (; j >= 0 && books.get(j).compareTo(book) > 0; j--) {
                    books.set(j + 1, books.get(j));
                }
                books.set(j + 1, book);
            }
        }
        public static void sort(List<Book> books, Comparator<Book> comparator) {
            for (int i = 1; i < books.size(); i++) {
                Book book = books.get(i);
                int j = i - 1;
                for (; j >= 0 && comparator.compare(books.get(j), book) > 0; j--){
                    books.set(j + 1, books.get(j));
                }
                books.set(j + 1, book);
            }
        }
    }

    static class TitleComparator implements Comparator<Book> {
        @Override
        public int compare(Book o1, Book o2) {
            return o1.title.compareTo(o2.title);
        }
    }

    static class PriceComparator implements Comparator<Book>{
        /**
         * true代表从小到大,false代表从大到小
         */
        boolean asc;

        public PriceComparator(boolean asc) {
            this.asc = asc;
        }


        @Override
        public int compare(Book o1, Book o2) {
            if(asc){
                return o1.price-o2.price;
            }else{
                return o2.price-o1.price;
            }
        }
    }
        public static void main(String[] args) {
            List<Book> books = new ArrayList<>();
            books.add(new Book("9787201151304", "从一到无穷大", "[美] 乔治·伽莫夫", 1600, 400, 26));
            books.add(new Book("9787020147465", "应物兄", "李洱", 7900, 1668, 300));
            books.add(new Book("9787220107085", "如何写甲骨文", "日本文字文化机构", 8800, 23, 6));
            books.add(new Book("9787521706635", "敌人与邻居", "[英]伊恩·布莱克", 10800, 3, 0));
            books.add(new Book("9787301280751", "法国大革命 (第2版)", "布兰宁(T.C.W.Blanning)", 4500, 1993, 188));

            List<Book> copy;

            // 按自然顺序(ISBN)排序
            System.out.println("按 ISBN 排序:");
            copy = new ArrayList<>(books);
            Sort.sort(copy);
            System.out.println(copy);

            // 按书名排序
            System.out.println("按 书名 排序:");
            copy = new ArrayList<>(books);
            Sort.sort(copy, new TitleComparator());
            System.out.println(copy);

            // 按价格排序-从小到大
            System.out.println("按 价格-从小到大 排序:");
            copy = new ArrayList<>(books);
            Sort.sort(copy, new PriceComparator(true));
            System.out.println(copy);

            // 按价格排序-从大到小
            System.out.println("按 价格-从大到小 排序:");
            copy = new ArrayList<>(books);
            Sort.sort(copy, new PriceComparator(false));
            System.out.println(copy);
        }
}

运行结果:
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值