Java比較器

導(dǎo)語

本節(jié)內(nèi)容娃善,比較器Comparable是核心內(nèi)容武契。

主要內(nèi)容

  • 重新認(rèn)識Arrays類
  • 兩種比較器的使用

具體內(nèi)容

Arrays類

在之前一直使用的“java.util.Arrays.sort()”可以實(shí)現(xiàn)數(shù)組的排序吊履,而Arrays類就是java.util包中提供的一個(gè)工具類醉箕,這個(gè)工具類主要是完成所有與數(shù)組有關(guān)的操作功能爬虱。

在這個(gè)類里面存在有二分查找法:public static int binarySearch(數(shù)據(jù)類型[] a, 數(shù)據(jù)類型 key)瞻离。但是如果要進(jìn)行二分查找,有一個(gè)前提临谱,那么就是數(shù)組必須是排序后的內(nèi)容璃俗。

范例:實(shí)現(xiàn)二分查找

public class TestDemo {
    public static void main(String args[]) {
        int data [] = new int [] {1, 5, 6, 2, 3, 4, 9, 8, 7, 10}; 
        java.util.Arrays.sort(data);  // 進(jìn)行排序
        System.out.println(Arrays.binarySearch(data, 9));
    }
}

輸出結(jié)果

8

Arrays類提供了數(shù)組比較:public static boolean equals(數(shù)據(jù)類型[] a, 數(shù)據(jù)類型[] a2),只不過借用了equals的方法名稱悉默,與Object類的equals()沒有關(guān)系城豁。

范例:實(shí)現(xiàn)二分查找

public class TestDemo {
    public static void main(String args[]) {
        int dataA [] = new int [] {1, 2, 3}; 
        int dataB [] = new int [] {2, 1, 3}; 
        int dataC [] = new int [] {1, 2, 3}; 
        System.out.println(Arrays.equals(dataA, dataB));
        System.out.println(Arrays.equals(dataA, dataC));
    }
}

輸出結(jié)果

false
ture

要想判斷數(shù)組是否相同,需要順序完全一致抄课。

  • 填充數(shù)組:public static void fill(數(shù)據(jù)類型[] a, 數(shù)據(jù)類型 val)唱星。
  • 將數(shù)組變?yōu)樽址敵觯簆ublic static String toString(數(shù)據(jù)類型[] a)。

范例:使用上面方法

public class TestDemo {
    public static void main(String args[]) {
        int data[] = new int[10];
        Arrays.fill(data, 3);
        System.out.println(Arrays.toString(data));
    }
}

輸出結(jié)果

[3, 3, 3, 3, 3, 3, 3, 3, 3, 3]

以上實(shí)際上就屬于數(shù)組的基本操作跟磨,只不過這樣的操作在實(shí)際的開發(fā)里面很少出現(xiàn)间聊。

比較器:Comparable(核心)

下面來觀察一下Arrays類中提供的數(shù)組排序方法:public static void sort(Object[] a)。
發(fā)現(xiàn)Arrays類里面可以直接利用sort()方法實(shí)現(xiàn)對象數(shù)組排序抵拘。

范例:編寫測試代碼

public class Book {
    private String title;
    private double price;
    public Book(String title, double price) {
    this.title = title;
    this.price = price;
    }
    public String to String() {
        return "書名:" + this.title + " 價(jià)格:" + this.price;
    }
}

public class TestDemo {
    public static void main(String args[]) {
        Book books [] = new Book [] {
                new Book("Java開發(fā)", 79.8), 
                new Book("JSP開發(fā)", 69.8), 
                new Book("Oracle開發(fā)", 99.8), 
                new Book("Android開發(fā)", 89.8), 
        };
        Arrays.sort(books);  // 對象數(shù)組排序
        System.out.println(Arrays.toString(books));
    }
}

輸出結(jié)果

Exception in thread "main" java.lang.ClassCastException:Book cannot be cast to java.lang.Comparable...

造成此類異常只有一個(gè)原因:丙個(gè)沒有關(guān)系的類對象發(fā)生了強(qiáng)制性的轉(zhuǎn)換哎榴。

每一個(gè)對象實(shí)際上只保留有地址信息,地址里面是有內(nèi)容的僵蛛,所以如果是普通的int型數(shù)組要進(jìn)行比較尚蝌,只要判斷大小就夠了,但是如果是對象數(shù)組充尉,里面包含的如果只是編碼(地址)比較是沒意義的飘言,就拿上面的代碼來講,應(yīng)該按照價(jià)格排序才是有意義的喉酌,所以此處必須要明確地設(shè)置出比較的規(guī)則:
比較的規(guī)則就是由Comparable接口定義的热凹,此接口定義如下:

public interface Comparable<T> {
    public int compareTo(T o);
}

實(shí)際上String類就是Comparable接口的子類,之前使用的compareTo()方法就是比較的操作功能泪电,如果用戶現(xiàn)在要針對于對象進(jìn)行比較般妙,建議compareTo()方法返回三類數(shù)據(jù):1(大于)、0(等于)相速、-1(小于)碟渺。

范例:使用比較器

public class Book implements Comparable<Book> {  // 實(shí)現(xiàn)比較
    private String title;
    private double price;
    public Book(String title, double price) {
    this.title = title;
    this.price = price;
    }
    @Override
    public String to String() {
        return "書名:" + this.title + " 價(jià)格:" + this.price;
    }
    @Override
    public int compareTo(Book o) {  // Arrays.sort()會(huì)自動(dòng)調(diào)用此方法比較
        if(this.price > o.price) {
            return 1;
        } else if(this.price < o.price) {
            return -1;
        } else {
            return 0;
        }
    }
}

public class TestDemo {
    public static void main(String args[]) {
        Book books [] = new Book [] {
                new Book("Java開發(fā)", 79.8), 
                new Book("JSP開發(fā)", 69.8), 
                new Book("Oracle開發(fā)", 99.8), 
                new Book("Android開發(fā)", 89.8), 
        };
        Arrays.sort(books);  // 對象數(shù)組排序
        System.out.println(Arrays.toString(books));
    }
}

輸出結(jié)果

[書名:JSP開發(fā) 價(jià)格:69.8, 書名:Java開發(fā) 價(jià)格:79.8, 書名:Android開發(fā) 價(jià)格:89.8, 書名:Oracle開發(fā) 價(jià)格:99.8]

compareTo()方法由Arrays.sort()自動(dòng)進(jìn)行調(diào)用。

以后不管何種情況下突诬,只要是一組對象要排序苫拍,對象所在的類一定要實(shí)現(xiàn)Comparable接口。

挽救的比較器:Comparator

Comparable接口的主要特征是在類定義的時(shí)候就默認(rèn)實(shí)現(xiàn)好的接口旺隙,那么如果說現(xiàn)在有一個(gè)類已經(jīng)開發(fā)完善了绒极。
但是由于初期的設(shè)計(jì)并沒有安排此類對象數(shù)組的排序,而后又突然需要實(shí)現(xiàn)對象數(shù)組的排序蔬捷,那么這個(gè)時(shí)候垄提,在不能修改Book類定義的情況下是不能使用Comparable接口的榔袋,為此,在Java里面為了解決這個(gè)問題铡俐,在Java里又出現(xiàn)了另一個(gè)比較器:java.util.Comparator凰兑。

原本在Comparator接口下有兩個(gè)方法:

@FunctionalInterface
public interface Comparator<T> {
    public int compare(T o1, T o2);
    public boolean equals(Object obj);
}

而真正要實(shí)現(xiàn)的只有compare()方法,需要單獨(dú)準(zhǔn)備出一個(gè)類來實(shí)現(xiàn)Comparator接口审丘,這個(gè)類將作為指定類的排序類吏够。

范例:定義排序的工具類

public class BookComparator implements Comparator<Book> {
    @Override
    public int compare(Book o1, Book o2) {
        if(o1.getPrice() > o2.getPrice()) {
            return 1;
        } else if(o1.getPrice() < o2.getPrice()) {
            return -1;
        } else {
            return 0;
        }
    }
}

之前使用Comparable接口的時(shí)候利用的是Arrays類中的sort()方法,可是現(xiàn)在更換了一個(gè)接口之后滩报,那么可以使用另外一個(gè)被重載的sort()方法:public static <T> void sort(T[] a, Comparator<? super T> c)锅知。

范例:實(shí)現(xiàn)排序

public class TestDemo {
    public static void main(String args[]) {
        Book books [] = new Book [] {
                new Book("Java開發(fā)", 79.8), 
                new Book("JSP開發(fā)", 69.8), 
                new Book("Oracle開發(fā)", 99.8), 
                new Book("Android開發(fā)", 89.8), 
        };
        Arrays.sort(books, new BookComparator());  // 對象數(shù)組排序
        System.out.println(Arrays.toString(books));
    }
}

輸出結(jié)果:

[書名:JSP開發(fā) 價(jià)格:69.8, 書名:Java開發(fā) 價(jià)格:79.8, 書名:Android開發(fā) 價(jià)格:89.8, 書名:Oracle開發(fā) 價(jià)格:99.8]

使用Comparator比較麻煩,因?yàn)橐x一個(gè)專門的排序類脓钾,而且調(diào)用排序的時(shí)候也要明確的指明一個(gè)排序規(guī)則類喉镰。

面試題:請解釋Comparable和Comparator的區(qū)別。

  • 如果對象數(shù)組要進(jìn)行排序那么必須設(shè)置排序規(guī)則惭笑,可以使用Comparable或Comparator接口實(shí)現(xiàn)。
  • java.lang.Comparable是在一個(gè)類定義的時(shí)候要去實(shí)現(xiàn)好的接口生真,這樣本類的對象數(shù)組就可以進(jìn)行排序沉噩,在Comparable接口下定義有一個(gè)public int compareTo()方法。
  • java.util.Comparator是專門定義一個(gè)指定類的比較規(guī)則柱蟀,屬于挽救的比較操作川蒙,里面有兩個(gè)方法:compare()、equals()长已。

總結(jié)

不管何種情況下畜眨,只要牽扯到對象數(shù)組的排序大多數(shù)使用Comparable接口。

更多內(nèi)容戳這里(整理好的各種文集)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末术瓮,一起剝皮案震驚了整個(gè)濱河市康聂,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌胞四,老刑警劉巖恬汁,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異辜伟,居然都是意外死亡氓侧,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進(jìn)店門导狡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來约巷,“玉大人,你說我怎么就攤上這事旱捧《览桑” “怎么了?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長囚聚。 經(jīng)常有香客問我靖榕,道長,這世上最難降的妖魔是什么顽铸? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任茁计,我火速辦了婚禮,結(jié)果婚禮上谓松,老公的妹妹穿的比我還像新娘星压。我一直安慰自己,他們只是感情好鬼譬,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布娜膘。 她就那樣靜靜地躺著,像睡著了一般优质。 火紅的嫁衣襯著肌膚如雪竣贪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天巩螃,我揣著相機(jī)與錄音演怎,去河邊找鬼。 笑死避乏,一個(gè)胖子當(dāng)著我的面吹牛爷耀,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播拍皮,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼歹叮,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了铆帽?” 一聲冷哼從身側(cè)響起咆耿,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎锄贼,沒想到半個(gè)月后票灰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡宅荤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年屑迂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片冯键。...
    茶點(diǎn)故事閱讀 39,769評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡惹盼,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出惫确,到底是詐尸還是另有隱情手报,我是刑警寧澤蚯舱,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站掩蛤,受9級特大地震影響枉昏,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜揍鸟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一兄裂、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧阳藻,春花似錦晰奖、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蛔外,卻和暖如春蛆楞,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背夹厌。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工臊岸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人尊流。 一個(gè)月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像灯帮,于是被迫代替她去往敵國和親崖技。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 從三月份找實(shí)習(xí)到現(xiàn)在钟哥,面了一些公司迎献,掛了不少,但最終還是拿到小米腻贰、百度吁恍、阿里、京東播演、新浪、CVTE、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,243評論 11 349
  • java筆記第一天 == 和 equals ==比較的比較的是兩個(gè)變量的值是否相等盛杰,對于引用型變量表示的是兩個(gè)變量...
    jmychou閱讀 1,497評論 0 3
  • 一洲炊、基本數(shù)據(jù)類型 注釋 單行注釋:// 區(qū)域注釋:/* */ 文檔注釋:/** */ 數(shù)值 對于byte類型而言...
    龍貓小爺閱讀 4,261評論 0 16
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法感局,類相關(guān)的語法尼啡,內(nèi)部類的語法,繼承相關(guān)的語法询微,異常的語法崖瞭,線程的語...
    子非魚_t_閱讀 31,625評論 18 399
  • 項(xiàng)目中經(jīng)常會(huì)遇到列表搜索查詢,大部分的查詢是可以通過sql語句來實(shí)現(xiàn)的撑毛,有些特殊的搜索排序sql則實(shí)現(xiàn)不了书聚,例如中...
    信徒_allen閱讀 2,584評論 0 1