才學(xué)了11條摊崭,我已經(jīng)感覺自己的Java基礎(chǔ)提升了一大截..
這一條是說「考慮實(shí)現(xiàn)Comparable接口」。
先了解一下Comparable接口杰赛。
首先是API呢簸,我粗略的翻譯:
這個(gè)接口對(duì)實(shí)現(xiàn)它的Object強(qiáng)加了一個(gè)total ordering(完全排序).這個(gè)ordering是class的natural ordering, class的 compareTo
方法是natural comparison method
。
由Objects組成的Lists(and arrays)可以通過 Collections.sort (and Arrays.sort) 來自動(dòng)排序乏屯。實(shí)現(xiàn)這個(gè)方法的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).
當(dāng)然,null不屬于Object蛤迎,e.compareTo(null)會(huì)拋出NullPointerException。
強(qiáng)烈建議(雖然不是必須)natural ordering 和 equals滿足一致性含友。因?yàn)閟orted sets和sorted maps在沒有explicit的comparators的時(shí)候替裆,當(dāng)他們?cè)诤筒粷M足一致性的elements或keys一起使用的時(shí)候會(huì)表現(xiàn)得 "strangely".
比如,如果加入兩個(gè)key窘问,a和b(such that (!a.equals(b) && a.compareTo(b) == 0) )到一個(gè)不實(shí)用explicit comparator的sorted set里辆童,第二個(gè)add operation 會(huì)返回false(set的大小也不會(huì)增加)因?yàn)樗麄儗?duì)于sorted set's來說是equivalent的(*筆者注:可以想像是因?yàn)閔ashmap這樣的map/set是把key的hash存在hash buckets里面的,這就說明對(duì)于set來說南缓,a和b的key一致胸遇,hash也一致。如果a,b的key不一致汉形,hash一致纸镊,就會(huì)出現(xiàn)hash碰撞,然后就用到?jīng)_突解決算法比如拉鏈法)概疆。
Virtually所有實(shí)現(xiàn)Comparable的Java核心類都有natural ordering that are consistent with equals逗威。
1、比較者大于被比較者(也就是compareTo方法里面的對(duì)象)岔冀,那么返回正整數(shù)
2凯旭、比較者等于被比較者,那么返回0
3使套、比較者小于被比較者罐呼,那么返回負(fù)整數(shù)
一個(gè)例子,可以看到排序的依據(jù)是自己定義的:
public class Field implements Comparable<Field> {
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來排序了侦高,這個(gè)sort會(huì)調(diào)用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<Field> list = new ArrayList<Field>();
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的區(qū)別
(這是一個(gè)常見的Java面試題..)
Java的Comparator和Comparable當(dāng)需要排序的集合或數(shù)組不是單純的數(shù)字型時(shí)嫉柴,通常可以使用Comparator或Comparable奉呛,以簡(jiǎn)單的方式實(shí)現(xiàn)對(duì)象排序或自定義排序计螺。
區(qū)別的話夯尽,我能看到的就是comparator是java.util里面的,說明它是一個(gè)util登馒;而comparable是java.lang里的,跟Object一個(gè)級(jí)別匙握,是一個(gè)基礎(chǔ)類。還有就是comparator支持升序降序等等更多功能陈轿。其他我不了解了圈纺,作為一個(gè)android出家的程序員也沒遇到過。麦射。
以上赠堵。
EJ里提到的
- compareTo的比較是順序的比較,不是等同性的比較法褥。
- 如果沒有實(shí)現(xiàn)comparable接口,或者需要非標(biāo)準(zhǔn)的排序酬屉,就可以使用Comparator來代替半等。
see also:
http://www.cnblogs.com/houziwty/p/5104845.html
http://www.cnblogs.com/szlbm/p/5504634.html