• 第12条: 考虑实现Comparable接口


    CompareTo方法没有在Object中声明,它是Comparable接口中的唯一的方法,不但允许进行简单的等同性比较,而且允许执行顺序比较。类实现了Comparable接口,就表明它的实例具有内在的排序关系。为实现Comparable接口的对象排序就这么简单:Arrays.sort(a);

    实现Comparable好处在于:一旦实现了Comparable接口,它可以跟许多泛型算法以及依赖于该接口的集合实现进行协作,只需付出很小的努力就可以获得非常强大的功能。
    Java平台的所有值类都实现了Comparable接口。如果一个类具有明显的内在排序关系,比如按字母顺序,按数字顺序,按年代顺序,就应该实现这个接口。

    CompareTo方法的通用约定:

      将这个对象与指定的对象进行比较。当该对象小于、等于、大于指定对象的时候,分别返回一个负整数、零或者正整数。如果由于指定对象的类型而无法与该对象进行比较,则抛出ClassCastException异常。

    如何很好的实现Comparable接口,根据CompareTo方法的通用约定我们可以总结出以下四点:
      (1)满足对称性。
        即对象A.comparaTo(B) 大于0的话,则B.comparaTo(A)必须小于0;
      (2)满足传递性。
        即对象A.comparaTo(B) 大于0,对象B.comparaTo(Z)大于0,则对象A.comparaTo(Z)一定要大于0;
      (3)建议comparaTo方法和equals()方法保持一致。
        即对象A.comparaTo(B)等于0,则建议A.equals(B)等于true。
      (4)对于实现了Comparable接口的类,尽量不要继承它,而是采取复合的方式。
      (5)一个建议,考虑BigDecimal类,它的compareTo方法和equals不一致,如果创建HashSet实例,并添加new BigDecimal("1.0") 和 new BigDecimal("1.00"),这个集合就将包含两个元素,因为HashSet通过equals比较是不相等的,然而,使用TreeSet来执行同样的过程,集合只包含一个元素,因为它是通过compareTo方法进行比较的。下面看下简单的comparTo例子:

    public class Person implements Comparable<Person>{
        private String name;
        private int age;
        private char sex;
        
        public Person(){}
        
        public Person(String name, int age, char sex) {
            this.name = name;
            this.age = age;
            this.sex = sex;
        }
    
        //String  Integer等实现了Comparable,所以字符串这些比较可以用它们重写的方法compareTo(),如“abc”.compareTo(“bcd”);会返回正反表示大小,0为相等
        public int compareTo(Person o) {
            //比较名字
            if(o.getName() == null || this.name == null){
                return -1;
            }
            return this.name.compareTo(o.getName());  //升序
        
            //按照年龄排序
            //return this.age - o.getAge();  //升序
        }
        public String toString(){
            return this.name +"---"+this.age;
        }
           //getter、setter方法...
    }
     public static void main(String[] args) {
            //根据姓名排序
            List<Person> list = new ArrayList<Person>();//初始化一个list
            list.add(new Person("b", 11, 'M'));
            list.add(new Person("a", 10, 'M'));
            list.add(new Person("c", 12, 'W'));
            Collections.sort(list); //集合排序,就是这么简单
            System.out.println(list);
            
            //根据age排序
            //将注释return this.age - o.getAge();去掉,把上面的注释掉
            Person[] array = new Person[]{new Person("aa", 21, 'M'),new Person("c", 11, 'M'),new Person("d", 31, 'M')};//初始化一个数组
            Arrays.sort(array); //数组排序,就是这么简单
            System.out.println(Arrays.toString(array));
     }

      

    好了,上面的comparable例子很简单吧。

    总结:什么时候应该考虑实现Comparable接口

      (1)你写的类是一个值类(前面的文章介绍过)。

      (2)类中有很明显的内在排序关系,如字母排序、按数值顺序或是时间等。

      (3)前面两者是并且关系。

    作者:哀&RT
    出处:博客园哀&RT的技术博客--http://www.cnblogs.com/Tony-Anne/
    您的支持是对博主最大的鼓励,感谢您的认真阅读。
    本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    NOI2010 超级钢琴
    [linux][nginx] 常用2
    [linux][nginx] 常用
    [PHP]听说随机数mt_rand()比rand()速度快,闲的无聊测试了一下!
    [linux] 权限问题
    [Laravel] 自带分页实现以及links方法不存在错误
    [YII2] 去除自带js,加载自己的JS,然后ajax(json)传值接值!
    [PHP]PHP设计模式:单例模式
    [html]浏览器标签小图标LOGO简单设置
    [javascript]JS获取当前时间戳的方法
  • 原文地址:https://www.cnblogs.com/Tony-Anne/p/6732432.html
Copyright © 2020-2023  润新知