A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 牛杨 中级黑马   /  2012-8-30 00:21  /  11332 人查看  /  10 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

API上说这个方法返回一个比较器,它强行逆转实现了 Comparable 接口的对象 collection 的自然顺序
我非常不明白为啥仅仅写这么一句  Collections.reverseOrder()  ;就可以让返回的比较器知道要排序那种类型的对象!
比如:
class Student implements  Comparable<Student>
{
      public int compareTo(Student s)
       {
              ………………
       }
}
Comparator<Student> cmp = Collections.reverseOrder();//这里得到的比较器怎么就那么智能地知道返回的一定是一个比较Student类型的对象啊?实现Comparable的类多了去了。为啥不返回其他的类的比较器呢?
关于这个方法的源代码也看了,但是没看懂{:soso_e127:}。希望哪个高人能够指点一下这个reverseOrder()方法的原理。


评分

参与人数 1技术分 +1 收起 理由
张立江 + 1

查看全部评分

10 个回复

正序浏览
学习了。。
回复 使用道具 举报
尤洋 发表于 2012-8-31 15:24
reverseOrder() 这个方法返回的类型是 Comparator,弄明白T的含义是什么,
就是你传入的是什么类型,它对应 ...

似乎有些明白了。但是关于reverseOrder方法的原理,就是源代码中关于那些很复杂的泛型使用。还是不太明白
回复 使用道具 举报
尤洋 中级黑马 2012-8-31 15:24:14
9#
reverseOrder() 这个方法返回的类型是 Comparator<T>,弄明白T的含义是什么,
就是你传入的是什么类型,它对应的就是那个类型
所以并不是 智能地知道返回的一定是一个比较Student类型的对象,而是你等式左边传进来的是Student,它对应的就是Student类型

评分

参与人数 1技术分 +1 收起 理由
张立江 + 1 赞一个!

查看全部评分

回复 使用道具 举报
牛杨 发表于 2012-8-30 17:14
兄弟你没没明白我说的什么意思。
你随便定义一个Person类,不去实现Comparable接口 下面照样运行成功。
C ...

是这样的,你定义的Person类里面应该会有String name,int age等变量,假设你的Person类的构造方法为Person(Sring name,int age),String是有实现Comparable接口的,那么Person的自然顺序就是String实现Comparable接口的顺序。所以不能说你的Person类没有实现Comparable接口。
回复 使用道具 举报
牛杨 中级黑马 2012-8-30 17:14:08
7#
周兴华 发表于 2012-8-30 16:52
reverseOrder() 这个方法返回一个比较器,它强行逆转实现了 Comparable 接口的对象 collection 的自然顺序 ...

兄弟你没没明白我说的什么意思。
你随便定义一个Person类,不去实现Comparable接口 下面照样运行成功。
Comparator<Person> cmp = Collections.reverseOrder();
回复 使用道具 举报
reverseOrder() 这个方法返回一个比较器,它强行逆转实现了 Comparable 接口的对象 collection 的自然顺序
注意,这里是指自然顺序。
如果不想要按照自然顺序,而是按照自己定义的比较器的顺序来逆转,那么可以用reverseOrder(Comparator<T> cmp)。
这里就会先有自定义个一个比较器cmp,然后用reverseOrder(new cmp())来返回需要的比较器

评分

参与人数 1技术分 +1 收起 理由
张立江 + 1 赞一个!

查看全部评分

回复 使用道具 举报
本帖最后由 牛杨 于 2012-8-30 16:48 编辑
杨卓儒 发表于 2012-8-30 13:34
public static  Comparator reverseOrder() {
        return (Comparator) REVERSE_ORDER;
    }

还是有些不理解 。你说 因为它压根儿就没识别 。这个我接受。但是能解释清楚些么?  这些源代码都没看懂。特别是那些泛型的使用。
回复 使用道具 举报
本帖最后由 杨卓儒 于 2012-8-30 13:43 编辑

    public static <T> Comparator<T> reverseOrder() {
        return (Comparator<T>) REVERSE_ORDER;
    }

    private static final Comparator REVERSE_ORDER = new ReverseComparator();

    /**
     * @serial include
     */
    private static class ReverseComparator<T>
        implements Comparator<Comparable<Object>>, Serializable {

        // use serialVersionUID from JDK 1.2.2 for interoperability
        private static final long serialVersionUID = 7207038068494060240L;
        
        //定义比较器的时候,不会要求传入对象类型,但是你如果使用compare方法的时候,总要传入两个参数吧,
        //即下面compare方法中的c1,与c2,那么这时比较器会返回相应对象类型。


        //因此,同时可以看出,如果在比较器没有定义泛型的话,在调用函数compare方法的时候,比较器会默认
        //载入调用对象的类型。因此楼主所顾虑的它为什么能自动识别就不存在了,因为它压根儿就没识别,只是
        //用的时候才会传入
        public int compare(Comparable<Object> c1, Comparable<Object> c2) {
            return c2.compareTo(c1);
        }
        private Object readResolve() { return reverseOrder(); }
    }

我是这么理解的,不知道对不对。






回复 使用道具 举报
谁知道 解答一下哦
回复 使用道具 举报
唉,难道没一个人能回答么?
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马