Java Comparable与Comparator的区别

Java 提供了两个接口来使用类的数据成员对对象进行排序:Comparable和Comparator。

Comparable

Comparable对象能够将自己与另一个对象进行比较。类本身必须实现java.lang.Comparable接口。
假设有一个Movie类,它的成员评分、名称、年份。如果希望根据年份对电影列表进行排序。可以用Movie类实现Comparable接口,重写Comparable接口的compareTo()方法。

    class Movie implements Comparable<Movie> {
        private double rating;
        private String name;
        private int year;

        // Used to sort movies by year
        public int compareTo(Movie m) {
            return this.year - m.year;
        }

        // Constructor
        public Movie(String nm, double rt, int yr) {
            this.name = nm;
            this.rating = rt;
            this.year = yr;
        }

        // Getter methods for accessing private data
        public double getRating() {
            return rating;
        }

        public String getName() {
            return name;
        }

        public int getYear() {
            return year;
        }
    }

    class Main {
        public static void main(String[] args) {
            ArrayList<Movie> list = new ArrayList<Movie>();
            list.add(new Movie("Force Awakens", 8.3, 2015));
            list.add(new Movie("Star Wars", 8.7, 1977));
            list.add(new Movie("Empire Strikes Back", 8.8, 1980));
            list.add(new Movie("Return of the Jedi", 8.4, 1983));

            Collections.sort(list);

            System.out.println("Movies after sorting : ");
            for (Movie movie : list) {
                System.out.println(movie.getName() + " " +
                        movie.getRating() + " " +
                        movie.getYear());
            }
        }
    }

现在,假设还想按电影的评分和名称对电影进行排序。当使一个集合元素具有可比性(通过让它实现 Comparable)时,只有一次机会实现 compareTo()方法。解决方案是使用比较器。

Comparator

与Comparable不同,Comparator在要比较的元素类型之外创建的单独的类。
Collections类有第二个sort()方法,它需要Comparator。sort()方法调用compare()对对象进行排序。
要按评分比较电影,需要做 3 件事:

  • 创建一个实现Comparator的类并实现compare() 方法。
  • 创建Comparator类的实例。
  • 调用重载的sort()方法,传入列表和实现Comparator的类的实例。
   class Movie implements Comparable<Movie> {
        private double rating;
        private String name;
        private int year;

        // Used to sort movies by year
        public int compareTo(Movie m) {
            return this.year - m.year;
        }

        // Constructor
        public Movie(String nm, double rt, int yr) {
            this.name = nm;
            this.rating = rt;
            this.year = yr;
        }

        // Getter methods for accessing private data
        public double getRating() {
            return rating;
        }

        public String getName() {
            return name;
        }

        public int getYear() {
            return year;
        }
    }

    // Class to compare Movies by ratings
    class RatingCompare implements Comparator<Movie> {
        public int compare(Movie m1, Movie m2) {
            if (m1.getRating() < m2.getRating()) return -1;
            if (m1.getRating() > m2.getRating()) return 1;
            else return 0;
        }
    }

    // Class to compare Movies by name
    class NameCompare implements Comparator<Movie> {
        public int compare(Movie m1, Movie m2) {
            return m1.getName().compareTo(m2.getName());
        }
    }

    // Driver class
    class Main {
        public static void main(String[] args) {
            ArrayList<Movie> list = new ArrayList<Movie>();
            list.add(new Movie("Force Awakens", 8.3, 2015));
            list.add(new Movie("Star Wars", 8.7, 1977));
            list.add(new Movie("Empire Strikes Back", 8.8, 1980));
            list.add(new Movie("Return of the Jedi", 8.4, 1983));

            // Sort by rating : (1) Create an object of ratingCompare
            //                  (2) Call Collections.sort
            //                  (3) Print Sorted list
            System.out.println("Sorted by rating");
            RatingCompare ratingCompare = new RatingCompare();
            Collections.sort(list, ratingCompare);
            for (Movie movie : list)
                System.out.println(movie.getRating() + " " +
                        movie.getName() + " " +
                        movie.getYear());


            // Call overloaded sort method with RatingCompare
            // (Same three steps as above)
            System.out.println("\nSorted by name");
            NameCompare nameCompare = new NameCompare();
            Collections.sort(list, nameCompare);
            for (Movie movie : list)
                System.out.println(movie.getName() + " " +
                        movie.getRating() + " " +
                        movie.getYear());

            // Uses Comparable to sort by year
            System.out.println("\nSorted by year");
            Collections.sort(list);
            for (Movie movie : list)
                System.out.println(movie.getYear() + " " +
                        movie.getRating() + " " +
                        movie.getName() + " ");
        }
    }

总结

  • Comparable适用于具有自然排序的对象,这意味着对象本身必须知道如何对其进行排序。例如学生人数。而Comparator接口排序是通过一个单独的类完成的。
  • 从逻辑上讲,Comparable接口将“this”引用与指定的对象进行比较,Java中的Comparator比较提供的两个不同的类对象。
  • 如果任何类在Java中实现Comparable接口,则可以使用Collections.sort()或Arrays.sort()方法自动对该对象的集合List或Array进行排序,并且对象将根据CompareTo方法定义的自然顺序进行排序。
  • 一个基本的区别特征是,使用Comparable只能使用一个比较。然而,可以为给定类型编写多个自定义比较器,所有这些都使用对排序含义的不同解释。就像在可比较的示例中一样,只能按一个属性(即年份)进行排序,但在比较器中,也可以使用不同的属性,例如评级、姓名和年份。

总而言之,如果对象的排序需要基于自然顺序,则使用Comparable,而如果需要对不同对象的属性进行排序,则使用Java中的 Comparator。

感谢大家的支持,如有错误请指正,如需转载请标明原文出处!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值