欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Comparator接口与Comparable接口

程序员文章站 2022-03-10 16:05:37
...

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相当于“外部比较器”。
示例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);
	}
}

运行结果:
Comparator接口与Comparable接口
示例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);
        }
}

运行结果:
Comparator接口与Comparable接口