Item 12: Consider implementing Comparable

才学了11条,我已经感觉自己的Java基础提升了一大截..
这一条是说「考虑实现Comparable接口」。
先了解一下Comparable接口。


首先是API,我粗略的翻译:

这个接口对实现它的Object强加了一个total ordering(完全排序).这个ordering是class的natural ordering, class的 compareTo方法是natural comparison method

由Objects组成的Lists(and arrays)可以通过 Collections.sort (and Arrays.sort) 来自动排序。实现这个方法的Objects可以被用作sorted map中的keys,或者sorted set中的elements(不需要指定comparator)。

natural ordering的意思是,be consistent with equals.
for every e1 and e2 of class C,
e1.compareTo(e2) == 0 has the same boolean value as e1.equals(e2).
当然,null不属于Object,e.compareTo(null)会抛出NullPointerException。

强烈建议(虽然不是必须)natural ordering 和 equals满足一致性。因为sorted sets和sorted maps在没有explicit的comparators的时候,当他们在和不满足一致性的elements或keys一起使用的时候会表现得 "strangely".

比如,如果加入两个key,a和b(such that (!a.equals(b) && a.compareTo(b) == 0) )到一个不实用explicit comparator的sorted set里,第二个add operation 会返回false(set的大小也不会增加)因为他们对于sorted set's来说是equivalent的(*笔者注:可以想像是因为hashmap这样的map/set是把key的hash存在hash buckets里面的,这就说明对于set来说,a和b的key一致,hash也一致。如果a,b的key不一致,hash一致,就会出现hash碰撞,然后就用到冲突解决算法比如拉链法)。

Virtually所有实现Comparable的Java核心类都有natural ordering that are consistent with equals。


1、比较者大于被比较者(也就是compareTo方法里面的对象),那么返回正整数

2、比较者等于被比较者,那么返回0

3、比较者小于被比较者,那么返回负整数

一个例子,可以看到排序的依据是自己定义的:

public class Field implements Comparable {

    private String name;
    private int age;

    public Field() {
    }
    public Field(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public int compareTo(Field o) {
        // 先按age排序
        if (this.age > o.getAge()) {
            return (this.age - o.getAge());
        }
        if (this.age < o.getAge()) {
            return (this.age - o.getAge());
        }
        // 按name排序
        if (this.name.compareTo(o.getName()) > 0) {
            return 1;
        }
        if (this.name.compareTo(o.getName()) < 0) {
            return -1;
        }
        return 0;
    }
}

然后就可以用放到Collections里面用它的sort来排序了,这个sort会调用compareTo

public class Test {
    public static void main(String[] args) {

        Field f1 = new Field("tony", 11);
        Field f2 = new Field("jack", 11);
        Field f3 = new Field("tom", 11);
        Field f4 = new Field("jason", 44);

        List list = new ArrayList();
        list.add(f1);
        list.add(f3);
        list.add(f4);
        list.add(f2);
        Collections.sort(list);

        for (Field o : list) {
            System.out.println(o.getAge() + "-->" + o.getName());
        }
    }
}

和Comparator的区别

(这是一个常见的Java面试题..)
Java的Comparator和Comparable当需要排序的集合或数组不是单纯的数字型时,通常可以使用Comparator或Comparable,以简单的方式实现对象排序或自定义排序。

区别的话,我能看到的就是comparator是java.util里面的,说明它是一个util;而comparable是java.lang里的,跟Object一个级别,是一个基础类。还有就是comparator支持升序降序等等更多功能。其他我不了解了,作为一个android出家的程序员也没遇到过。。

以上。

EJ里提到的

Item 12: Consider implementing Comparable_第1张图片
CONVENTIONS.png
  • compareTo的比较是顺序的比较,不是等同性的比较。
  • 如果没有实现comparable接口,或者需要非标准的排序,就可以使用Comparator来代替。
    see also:
    http://www.cnblogs.com/houziwty/p/5104845.html
    http://www.cnblogs.com/szlbm/p/5504634.html

你可能感兴趣的:(Item 12: Consider implementing Comparable)