zoukankan      html  css  js  c++  java
  • Java中的比较器(Comparable和Comparator)

      在Java中,正常情况下,对象不能使用<、>进行比较,排序,而在开发中我们又需要对对象进行排序,比如TreeMap、TreeSet,再往里面添加数据时,需要让添加进去的对象排序好,这时就需要使用两个接口中的一个:Comparable和Comparator。

      很多情况下,我们需要对数据进行排序,但是java自带的比较器只能比较基本数据类型,比如我们自己定义一个Student类,如果用默认的Array.sort()方法进行排序,他会按照内存地址进行排序,那么这个排序毫无意义,此时我们就需要自己定义一个比较器,按照我们想要的比较方式来进行排序。

    Comparable

      所有可以排序的类都实现了java.lang.Comparable接口,Comparable接口中只有一个方法:compareTo(Object obj),该方法返回0表示this==obj、返回正数表示this>obj、返回负数表示this<obj,实现了Comparable接口的类通过实现comparaTo方法从而确定该类对象的排序方式。

      一般被集合元素类所实现。

    public class Student implements Comparable<Student>{
        /**
         * 编号
         */
        private int id;
    
        /**
         * 姓名
         */
        private String name;
    
        /**
         * 通过学生编号进行排序
         * @param o
         * @return
         */
        @Override
        public int compareTo(Student o) {
            return this.id - o.id;
        }
    }
    

    Comparator

      Comparator可以认为是一个外比较器,在一个对象不支持自己和自己比较(没有实现Comparable接口),但是又想对两个对象进行比较的情况下可以使用,Comparator接口里有一个compara(T o1, T o2)方法,方法有两个参数T o1和T o2,是泛型的表示方式,分别表示待比较的两个对象,方法返回值和Comparable接口一样是int,有三种情况:

    • o1大于o2,返回正整数
    • o1等于o2,返回零
    • o1小于o2,返回负整数

      Comparator接口一般有两种实现方式,单独实现,或者匿名内部类方式实现。

    匿名内部类实现方式:

    public class TreeSetDemo {
        public static void main(String[] args) {
            Set set = new TreeSet(new Comparator() {
                @Override
                public int compare(Object o1, Object o2) {
                    Clazz c1 = (Clazz) o1;
                    Clazz c2 = (Clazz) o2;
                    return c1.getId() - c2.getId();
                }
            });
            set.add(new Clazz(1,"name1"));
            set.add(new Clazz(2,"name2"));
            set.add(new Clazz(3,"name3"));
            // 遍历set
            for (Object obj : set) {
                System.out.println(obj);
            }
        }
    }
    

    单独实现:

    public class TreeSetDemo {
        public static void main(String[] args) {
            Set set = new TreeSet(new ClazzComparatorOrder(false));
            set.add(new Clazz(1,"name1"));
            set.add(new Clazz(2,"name2"));
            set.add(new Clazz(3,"name3"));
            // 遍历set
            for (Object obj : set) {
                System.out.println(obj);
            }
        }
    
        /**
         * 排序器,静态内部类
         */
        private static class ClazzComparatorOrder implements Comparator {
    
            /**
             * 正向或逆向排序的标志
             */
            private boolean flag;
            /**
             * 排序器构造方法
             * @param flag 正向或逆向排序的标志
             */
            private ClazzComparatorOrder(boolean flag) {
                this.flag = flag;
            }
            @Override
            public int compare(Object o1, Object o2) {
                Clazz c1 = (Clazz) o1;
                Clazz c2 = (Clazz) o2;
                if (this.flag) {
                    // 正向
                    return c1.getId() - c2.getId();
                } else {
                    // 逆向
                    return c2.getId() - c1.getId();
                }
            }
        }
    }
    

    好处:可以通过构造方法输入true或者false来控制正向或逆向排序。

    Comparable 与 Comparator的区别

    • 如果对象数组需要排序,那么就必须设置排序规则,就要使用这两种比较器。

    • 对于Comparable接口来说,它往往是进行比较类需要实现的接口,它仅包含一个有comparaTo()方法,只有一个参数。

    • 对于Comparator接口来说,它的实现者被称为比较器,它包含一个compara()方法,有两个参数,Comparator接口一般不会被集合元素类所实现,而是单独实现或者匿名内部类实现

    • Comparable接口的方式一旦实现,就可以保证Comparable的实现类在任何位置都可以比较大小。

    • Comparator接口属于临时性比较。

    • 如果实现类没有实现Comparable接口,又想对两个类进行比较(或者实现类实现了Comparable接口,但是对compareTo方法内的比较算法不满意),那么可以实现Comparator接口,自定义一个比较器,写比较算法。

    • 实现Comparable接口的方式比实现Comparator接口的耦合性要强一些,如果要修改比较算法,要修改Comparable接口的实现类,而实现Comparator的类是在外部进行比较的,不需要对实现类有任何修改。从这个角度说,其实有些不太好,尤其在我们将实现类的.class文件打成一个.jar文件提供给开发者使用的时候。

  • 相关阅读:
    EasyPlayer iOS开源流媒体播放器中AAC解码PCM问题
    EasyPlayer iOS开源流媒体播放器中AAC解码PCM问题
    AAC包增加ADTS头Without MediaCodec
    AAC包增加ADTS头Without MediaCodec
    嵌入式流媒体音视频服务器EasyIPCamera中live555发送性能优化点
    嵌入式流媒体音视频服务器EasyIPCamera中live555发送性能优化点
    EasyDarwin开源流媒体服务器性能优化之Work-stealing优化方案
    EasyDarwin开源流媒体服务器性能优化之Work-stealing优化方案
    Visual Studio解决方案vs2005/vs2008/vs2010/vs2012/vs2013/vs2015版本互相转换工具
    Visual Studio解决方案vs2005/vs2008/vs2010/vs2012/vs2013/vs2015版本互相转换工具
  • 原文地址:https://www.cnblogs.com/zbh355376/p/14617154.html
Copyright © 2011-2022 走看看