List集合排序Collections.sort()方法的一個容易忽略的小問題

很多人對list集合排序時喜歡實現(xiàn)Comparator<T>接口,自己定義排序方式,例如:

Listlist = new ArrayList<>();

list.add(1);

list.add(7);

list.add(3);

list.add(6);

list.add(5);

list.add(5);

System.out.println("排序前:");

for (int i : list) {??

? System.out.println(i);

}

Collections.sort(list, new Comparator() {?

??public int compare(Integer o1, Integer o2) {??

? ? ? return o1-o2;? ? }

});

System.out.println("排序后:");

for (int i : list) {? ? System.out.println(i);}

輸出信息:

排序前:

1

7

3

6

5

5

排序后:

1

3

5

5

6

7

這樣沒有問題,但是如果int換成long呢?只有改成這樣:

Collections.sort(list, new Comparator() {? ??

public int compare(Long l1, Long l2) {?

?? ? ? return (int) (l1-l2);? ? }

});

輸出信息:

排序前:

1

7

3

6

5

5

排序后:

1

3

5

5

6

7

這樣看上去也沒有問題,但是如果long的數(shù)值過大呢?比如數(shù)據(jù)添加兩行:

Listlist = new ArrayList<>();

list.add(1L);

list.add(7L);

list.add(3L);

list.add(6L);

list.add(5L);

list.add(5L);

list.add(1247189571876180L);

list.add(52856189568195L);

然而打印便成了這樣:

排序前:

1

7

3

6

5

5

1247189571876180

52856189568195

排序后:

52856189568195

1247189571876180

1

3

5

5

6

7

這是為什么呢?這是因為52856189568195這樣的數(shù)字與1這樣的數(shù)字做減法運(yùn)算后他的數(shù)值超過了int的范圍,做強(qiáng)轉(zhuǎn)時造成了數(shù)據(jù)丟失,所以我們這樣做減法再強(qiáng)轉(zhuǎn)的方式明顯不可取,所以我們可以用這樣的方式去解決這個問題:

Collections.sort(list, new Comparator() {

public int compare(Long l1, Long l2) {

? ? ? ? return Long.compare(l1,l2);? ??

});

打印信息便正常了:

排序前:

1

7

3

6

5

5

1247189571876180

52856189568195

排序后:

1

3

5

5

6

7

52856189568195

1247189571876180

這個方法不是Long獨(dú)有的,Integer,Double甚至String都有,這個方法也可以寫成這樣:l1.compareTo(l2),特別注意的是String,它沒有compare方法,只有compareTo方法,為什么使用這個方法就可以避免數(shù)據(jù)丟失呢?我們來看源碼:

public static int compare(long x, long y) {

? ? return (x < y) ? -1 : ((x == y) ? 0 : 1);

}

public int compareTo(Long anotherLong) {

? ? return compare(this.value, anotherLong.value);

}

源碼中沒有進(jìn)行強(qiáng)轉(zhuǎn),用的是一個三元運(yùn)算符,這個相信大家都看得懂,屬于java基礎(chǔ)內(nèi)容,我就不獻(xiàn)丑去解釋了,到這里就會有人說了,我為什么要用差距這么大數(shù)去排序呢?emmm...別急,繼續(xù)往下看:

有這么一個較復(fù)雜的數(shù)據(jù):

public class TestBean {

? ? private int id;

? ? private String name;

? ? private Date createDate;

? ? private Date updateDate;

? ? public TestBean(int id, String name, Date createDate, Date updateDate) {

? ? ? ? this.id = id;

? ? ? ? this.name = name;

? ? ? ? this.createDate = createDate;

? ? ? ? this.updateDate = updateDate;

? ? }

}

我們想對它進(jìn)行排序,按創(chuàng)建時間排序,創(chuàng)建時間一樣按姓名排序,我們就可以這么寫:

Listlist = new ArrayList<>();list.add(new TestBean(1,"德瑪西亞劉德華",new Date(0),new Date(0)));list.add(new TestBean(2,"艾歐里亞張學(xué)友",new Date(System.currentTimeMillis()),new Date(0)));

list.add(new TestBean(3,"諾克薩斯彭于晏",new Date(1213846185668L),new Date(0)));

list.add(new TestBean(4,"弗雷爾卓德黎明",new Date(13575917L),new Date(0)));

list.add(new TestBean(5,"皮城美少女戰(zhàn)士",new Date(13575917L),new Date(0)));

System.out.println("排序前:");

for (TestBean b : list) {?

?? System.out.println(b.toString());

}

Collections.sort(list, new Comparator() {

?public int compare(TestBean b1, TestBean b2) {

? ? ? ? if (b1.getCreateDate().getTime()-b2.getCreateDate().getTime()!=0){? ?

?? ? ? ? return Long.compare(b1.getCreateDate().getTime(),b2.getCreateDate().getTime());? ? ? ??

}else {? ? ? ? ? ??

return b1.getName().compareTo(b2.getName());? ? ? ??

}

}});

System.out.println("排序后:");

for (TestBean i : list) {

? ? System.out.println(i.toString());

}

打印信息為:

排序前:

TestBean{id=1, name='德瑪西亞劉德華', createDate=Thu Jan 01 08:00:00 CST 1970, updateDate=Thu Jan 01 08:00:00 CST 1970}

TestBean{id=2, name='艾歐里亞張學(xué)友', createDate=Tue Dec 11 22:36:01 CST 2018, updateDate=Thu Jan 01 08:00:00 CST 1970}

TestBean{id=3, name='諾克薩斯彭于晏', createDate=Thu Jun 19 11:29:45 CST 2008, updateDate=Thu Jan 01 08:00:00 CST 1970}

TestBean{id=4, name='弗雷爾卓德黎明', createDate=Thu Jan 01 11:46:15 CST 1970, updateDate=Thu Jan 01 08:00:00 CST 1970}

TestBean{id=5, name='皮城美少女戰(zhàn)士', createDate=Thu Jan 01 11:46:15 CST 1970, updateDate=Thu Jan 01 08:00:00 CST 1970}

排序后:

TestBean{id=1, name='德瑪西亞劉德華', createDate=Thu Jan 01 08:00:00 CST 1970, updateDate=Thu Jan 01 08:00:00 CST 1970}

TestBean{id=4, name='弗雷爾卓德黎明', createDate=Thu Jan 01 11:46:15 CST 1970, updateDate=Thu Jan 01 08:00:00 CST 1970}

TestBean{id=5, name='皮城美少女戰(zhàn)士', createDate=Thu Jan 01 11:46:15 CST 1970, updateDate=Thu Jan 01 08:00:00 CST 1970}

TestBean{id=3, name='諾克薩斯彭于晏', createDate=Thu Jun 19 11:29:45 CST 2008, updateDate=Thu Jan 01 08:00:00 CST 1970}

TestBean{id=2, name='艾歐里亞張學(xué)友', createDate=Tue Dec 11 22:36:01 CST 2018, updateDate=Thu Jan 01 08:00:00 CST 1970}

你們看,這樣不但代碼簡潔,而且出現(xiàn)錯誤的幾率也更小是不是?本人也是個新人程序員,說的不對的地方大家可以指正,希望我們可以一起努力,早日成為大家都想成為的大神!加油,(=?ω?)? ---===≡≡≡

大家看不清楚可以去我在CSDN發(fā)的文章https://blog.csdn.net/tp19970424/article/details/84962584,因為懶,所以我是粘貼復(fù)制的,不想再打一遍了...

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末酬屉,一起剝皮案震驚了整個濱河市炬守,隨后出現(xiàn)的幾起案子煌茴,更是在濱河造成了極大的恐慌境蜕,老刑警劉巖方面,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件兔综,死亡現(xiàn)場離奇詭異颂碧,居然都是意外死亡始锚,警方通過查閱死者的電腦和手機(jī)瘪阁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進(jìn)店門撒遣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人管跺,你說我怎么就攤上這事义黎。” “怎么了豁跑?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵廉涕,是天一觀的道長。 經(jīng)常有香客問我艇拍,道長狐蜕,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任卸夕,我火速辦了婚禮馏鹤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘娇哆。我一直安慰自己湃累,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布碍讨。 她就那樣靜靜地躺著治力,像睡著了一般。 火紅的嫁衣襯著肌膚如雪勃黍。 梳的紋絲不亂的頭發(fā)上宵统,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼马澈。 笑死瓢省,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的痊班。 我是一名探鬼主播勤婚,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼涤伐!你這毒婦竟也來了馒胆?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤凝果,失蹤者是張志新(化名)和其女友劉穎祝迂,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體器净,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡型雳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了山害。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片纠俭。...
    茶點(diǎn)故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖粗恢,靈堂內(nèi)的尸體忽然破棺而出柑晒,到底是詐尸還是另有隱情,我是刑警寧澤眷射,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布匙赞,位于F島的核電站,受9級特大地震影響妖碉,放射性物質(zhì)發(fā)生泄漏涌庭。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一欧宜、第九天 我趴在偏房一處隱蔽的房頂上張望坐榆。 院中可真熱鬧,春花似錦冗茸、人聲如沸席镀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽豪诲。三九已至,卻和暖如春挂绰,著一層夾襖步出監(jiān)牢的瞬間屎篱,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留交播,地道東北人重虑。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像秦士,于是被迫代替她去往敵國和親缺厉。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評論 2 349

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