淺談Java中Collections.sort對(duì)List排序的兩種方法
一、Collections.sort的簡(jiǎn)單使用
說到List的排序,第一反應(yīng)當(dāng)然是使用Collections.sort,方便簡(jiǎn)單。下面實(shí)現(xiàn)一下~~
private void sortStrings() {
List<String> list = new ArrayList<String>();
list.add("ccc");
list.add("aaa");
list.add("bbb");
//排序
Collections.sort(list);
//輸出
Log.d(TAG, "-----------對(duì)字符串排序-----------");
for(String item : list) {
Log.d(TAG, item.toString());
}
}
=02-03 10:32:25.821: D/wxx(4732): -----------對(duì)字符串排序-----------
02-03 10:32:25.821: D/wxx(4732): aaa
02-03 10:32:25.821: D/wxx(4732): bbb
02-03 10:32:25.821: D/wxx(4732): ccc
可見,實(shí)現(xiàn)了對(duì)List<String>的排序,非常簡(jiǎn)單。
二、問題提出
但在我們的項(xiàng)目中列表List的元素類型經(jīng)常是自定義的,下面自定義了一個(gè)實(shí)體類Person:
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
然后,想對(duì)Person的列表List<Person>進(jìn)行排序,首先想到的也是通過Collections.sort進(jìn)行排序:
private void sortPerson() {
Person p1 = new Person("ccc", 20);
Person p2 = new Person("aaa", 18);
Person p3 = new Person("bbb", 16);
List<Person> list = new ArrayList<Person>();
list.add(p1);
list.add(p2);
list.add(p3);
//排序
Collections.sort(list);
}
發(fā)現(xiàn),代碼直接報(bào)錯(cuò)了:
Bound mismatch: The generic method sort(List<T>) of type Collections is not applicable for the arguments (List<Person>). The inferred type Person is not a valid substitute for the bounded
?parameter <T extends Comparable<? super T>>
從上面可知,Person不是一個(gè)有效的參數(shù)類型,而應(yīng)該extends Comparable。為什么?
原來,要排序嘛當(dāng)然要有排序的規(guī)則,比如按身高從高到低,按年齡從小到大,等等,也就是要有比較。而String這個(gè)對(duì)象已經(jīng)幫我們實(shí)現(xiàn)了Comparable接口,所以String類型自己就是可以比較的。而我們的Person如果想要排序,也必須能夠按某種規(guī)則進(jìn)行比較,也就是要實(shí)現(xiàn)一個(gè)比較器。我們可以通過實(shí)現(xiàn)Comparable或Comparator接口實(shí)現(xiàn)比較器 。
三、Comparable實(shí)現(xiàn)排序
Comparable實(shí)現(xiàn)比較器,是定義在Person類的內(nèi)部的,所以實(shí)體類Person需要implements Comparable<Person>,然后重寫compareTo方法,在此方法里實(shí)現(xiàn)比較規(guī)則,規(guī)則就是先比較名字,如果名字不一樣則返回比較結(jié)果,如果名字一樣,再比較年齡,返回比較結(jié)果:
public class Person implements Comparable<Person> {
public String name;
public int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public int compareTo(Person another) {
int i = name.compareTo(another.name); //比較名字字符串
if (i == 0) { //如果名字一樣,則繼續(xù)比較年齡
return age - another.age;
} else { //首先比較名字,名字不一樣,則返回比較結(jié)果
return i;
}
}
}
后面就是對(duì)List<Person>進(jìn)行排序并輸出:
private void sortByComparable() {
Person p1 = new Person("bbb", 20);
Person p2 = new Person("aaa", 18);
Person p3 = new Person("bbb", 16);
List<Person> list = new ArrayList<Person>();
list.add(p1);
list.add(p2);
list.add(p3);
//排序
Collections.sort(list);
//輸出
Log.d(TAG, "-----------使用Comparable實(shí)現(xiàn)的排序-----------");
for(Person item : list) {
Log.d(TAG, "name = "+item.name+", age = "+item.age);
}
}
檢查輸出結(jié)果是否正確:
02-03 12:05:31.356: D/wxx(9936): -----------使用Comparable實(shí)現(xiàn)的排序-----------
02-03 12:05:31.356: D/wxx(9936): name = aaa, age = 18
02-03 12:05:31.356: D/wxx(9936): name = bbb, age = 16
02-03 12:05:31.356: D/wxx(9936): name = bbb, age = 20
四、Comparator實(shí)現(xiàn)排序
Comparator實(shí)現(xiàn)比較器,是定義在Person類的外部的,因此實(shí)體類Person不需要做任何變化,如下:
public class Person {
public String name;
public int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
我們的比較器My Comparator的實(shí)現(xiàn),主要是覆蓋compare方法,在這個(gè)方法內(nèi)實(shí)現(xiàn)比較的規(guī)則,具體代碼:
public class MyComparator implements Comparator<Person> {
public int compare(Person one, Person two) {
int i = one.name.compareTo(two.name); //比較名字字符串
if (i == 0) { //如果名字一樣,則繼續(xù)比較年齡
return one.age - two.age;
} else { //首先比較名字,名字不一樣,則返回比較結(jié)果
return i;
}
}
}
上面的排序規(guī)則是:先比較name值進(jìn)行排序,如果name值一樣 ,再比較age值排序。
最后,當(dāng)然是用我們的比較器對(duì)List<Person>進(jìn)行排序:
private void sortByComparator() {
Person p1 = new Person("bbb", 20);
Person p2 = new Person("aaa", 18);
Person p3 = new Person("bbb", 16);
List<Person> list = new ArrayList<Person>();
list.add(p1);
list.add(p2);
list.add(p3);
//排序
Collections.sort(list, new MyComparator());
//輸出
Log.d(TAG, "-----------使用Comparator實(shí)現(xiàn)的排序-----------");
for(Person item : list) {
Log.d(TAG, "name = "+item.name+", age = "+item.age);
}
}
查看排序后的輸出結(jié)果是否正確:
02-03 11:51:34.996: D/wxx(1355): -----------使用Comparator實(shí)現(xiàn)的排序-----------
02-03 11:51:34.996: D/wxx(1355): name = aaa, age = 18
02-03 11:51:35.001: D/wxx(1355): name = bbb, age = 16
02-03 11:51:35.001: D/wxx(1355): name = bbb, age = 20
五、Comparable 與Comparator區(qū)別
上面已經(jīng)分別實(shí)現(xiàn)了Comparable 與Comparator對(duì)List進(jìn)行排序,他們有相似的地方,也有不同的地方:
1)Comparable 與Comparator都是java的接口,用來對(duì)自定義的實(shí)體對(duì)象進(jìn)行比較;
2)Comparable 是定義在實(shí)體類內(nèi)部的,所以實(shí)體類對(duì)象本身就有比較大小的可能。但如果想換一種比較規(guī)則,如先按年齡后按名字排序,那么就必須修改實(shí)體類Person本身;
3)Comparator是在實(shí)體類外部實(shí)現(xiàn)比較器的,所以對(duì)List排序時(shí)必須同時(shí)傳入數(shù)據(jù)和比較器,如Collections.sort(list, new MyComparator());如果想換一種比較規(guī)則,則僅需要修改比較器MyComparator,而實(shí)體類Person則不需要改變;所以建議使用這種方法;
4)Comparable實(shí)現(xiàn)代碼相對(duì)簡(jiǎn)單,Comparator實(shí)現(xiàn)代碼相對(duì)復(fù)雜一點(diǎn),但還是建議使用Comparator方法。
到此這篇關(guān)于淺談Java中Collections.sort對(duì)List排序的兩種方法的文章就介紹到這了,更多相關(guān)Java中Collections.sort List排序 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- java.util.Collections類—emptyList()方法的使用
- Java使用Collections.sort()排序的方法
- java安全之CommonsCollections4詳解
- Java中的Collections類的使用示例詳解
- Java中Collections.sort的使用
- Java的可變參數(shù)與Collections類的功能示例解析
- Java中Collection與Collections的區(qū)別詳解
- Java Collection和Collections的區(qū)別
- Java中的集合工具類Collections詳解
- Java中Collections.sort()排序方法舉例詳解
- Java中Collection和Collections的區(qū)別
相關(guān)文章
Springboot+WebSocket+Netty實(shí)現(xiàn)在線聊天/群聊系統(tǒng)
這篇文章主要實(shí)現(xiàn)在好友添加、建群、聊天對(duì)話、群聊功能,使用Java作為后端語言進(jìn)行支持,界面友好,開發(fā)簡(jiǎn)單,文章中有詳細(xì)的代碼示例供大家參考,需要的朋友可以參考下2023-08-08
ReadWriteLock接口及其實(shí)現(xiàn)ReentrantReadWriteLock方法
下面小編就為大家?guī)硪黄猂eadWriteLock接口及其實(shí)現(xiàn)ReentrantReadWriteLock方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-06-06
淺談Java HttpURLConnection請(qǐng)求方式
這篇文章主要介紹了淺談Java HttpURLConnection請(qǐng)求方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-08-08
解釋為什么Java中“1000==1000”為false而”100==100“為true
在日常編程中,我們經(jīng)常遇到一些看似簡(jiǎn)單卻隱藏著復(fù)雜邏輯的問題,這篇文章主要介紹了解釋為什么Java中“1000==1000”為false而”100==100“為true,需要的朋友可以參考下2024-01-01
關(guān)于Gateway網(wǎng)關(guān)中配置跨域的三種方案
文章總結(jié):介紹了三種處理跨域請(qǐng)求的方法:在Controller類上添加注解、通過配置類實(shí)現(xiàn)重寫WebMvcConfigurer接口和在配置文件中統(tǒng)一設(shè)置,希望這些方法能幫助讀者解決跨域問題2024-11-11
Netty之使用DelimiterBasedFrameDecoder進(jìn)行消息分隔詳解
這篇文章主要介紹了Netty之使用DelimiterBasedFrameDecoder進(jìn)行消息分隔詳解,在使用Netty進(jìn)行TCP消息傳輸時(shí),為了上層協(xié)議能夠?qū)ο⒄_區(qū)分,避免粘包和拆包導(dǎo)致的問題,一般可以通過消息定長(zhǎng)、將回車換行符作為消息結(jié)束符,需要的朋友可以參考下2023-12-12
詳解Java中的時(shí)間處理與時(shí)間標(biāo)準(zhǔn)
這篇文章主要為大家詳細(xì)介紹了三個(gè)時(shí)間標(biāo)準(zhǔn)GMT,CST,UTC的規(guī)定,以及Java進(jìn)行時(shí)間處理的相關(guān)知識(shí),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-09-09

