java?集合工具類Collections及Comparable和Comparator排序詳解
一、常用功能
java.utils.Collections
是集合工具類,用來(lái)對(duì)集合進(jìn)行操作。
部分方法如下:
public static <T> boolean addAll(Collection<T> c, T... elements)
:往集合中添加一些元素。public static void shuffle(List<?> list) 打亂順序
:打亂集合順序。public static <T> void sort(List<T> list)
:將集合中元素按照默認(rèn)規(guī)則排序。public static <T> void sort(List<T> list,Comparator<? super T> )
:將集合中元素按照指定規(guī)則排序。
代碼演示:
public class CollectionsDemo { public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<Integer>(); //原來(lái)寫(xiě)法 //list.add(12); //list.add(14); //list.add(15); //list.add(1000); //采用工具類 完成 往集合中添加元素 Collections.addAll(list, 5, 222, 1,2); System.out.println(list); //排序方法 Collections.sort(list); System.out.println(list); } }
結(jié)果:
[5, 222, 1, 2]
[1, 2, 5, 222]
代碼演示之后 ,發(fā)現(xiàn)我們的集合按照順序進(jìn)行了排列,可是這樣的順序是采用默認(rèn)的順序,如果想要指定順序那該怎么辦呢? 我們發(fā)現(xiàn)還有個(gè)方法沒(méi)有講,public static <T> void sort(List<T> list,Comparator<? super T> )
:將集合中元素按照指定規(guī)則排序。接下來(lái)講解一下指定規(guī)則的排列。
二、Comparator比較器
我們還是先研究這個(gè)方法 public static <T> void sort(List<T> list)
:將集合中元素按照默認(rèn)規(guī)則排序。 不過(guò)這次存儲(chǔ)的是字符串類型。
public class CollectionsDemo2 { public static void main(String[] args) { ArrayList<String> list = new ArrayList<String>(); list.add("cba"); list.add("aba"); list.add("sba"); list.add("nba"); //排序方法 Collections.sort(list); System.out.println(list); } }
結(jié)果:
[aba, cba, nba, sba]
我們使用的是默認(rèn)的規(guī)則完成字符串的排序,那么默認(rèn)規(guī)則是怎么定義出來(lái)的呢? 說(shuō)到排序了,簡(jiǎn)單的說(shuō)就是兩個(gè)對(duì)象之間比較大小,那么在JAVA中提供了兩種比較實(shí)現(xiàn)的方式,一種是比較死板的采用java.lang.Comparable
接口去實(shí)現(xiàn),一種是靈活的當(dāng)我需要做排序的時(shí)候在去選擇的java.util.Comparator
接口完成。 那么我們采用的public static <T> void sort(List<T> list)
這個(gè)方法完成的排序,實(shí)際上要求了被排序的類型需要實(shí)現(xiàn)Comparable接口完成比較的功能,
在String類型上如下:
public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
String類實(shí)現(xiàn)了這個(gè)接口,并完成了比較規(guī)則的定義,但是這樣就把這種規(guī)則寫(xiě)死了,那比如我想要字符串按照第一個(gè)字符降序排列,那么這樣就要修改String的源代碼,這是不可能的了,那么這個(gè)時(shí)候我們可以使用 public static <T> void sort(List<T> list,Comparator<? super T> )
方法靈活的完成,這個(gè)里面就涉及到了Comparator這個(gè)接口,位于位于java.util包下,排序是comparator能實(shí)現(xiàn)的功能之一,該接口代表一個(gè)比較器,比較器具有可比性!顧名思義就是做排序的,通俗地講需要比較兩個(gè)對(duì)象誰(shuí)排在前誰(shuí)排在后,那么比較的方法就是:
public int compare(String o1, String o2)
:比較其兩個(gè)參數(shù)的順序。
兩個(gè)對(duì)象比較的結(jié)果有三種:大于,等于,小于。 如果要按照升序排序,
則o1 小于o2,返回(負(fù)數(shù)),相等返回0,01大于02返回(正數(shù)) 如果要按照降序排序 則o1 小于o2,返回(正數(shù)),相等返回0,01大于02返回(負(fù)數(shù))
操作如下:
public class CollectionsDemo3 { public static void main(String[] args) { ArrayList<String> list = new ArrayList<String>(); list.add("cba"); list.add("aba"); list.add("sba"); list.add("nba"); //排序方法 按照第一個(gè)單詞的降序 Collections.sort(list, new Comparator<String>() { @Override public int compare(String o1, String o2) { return o2.charAt(0) - o1.charAt(0); } }); System.out.println(list); } }
結(jié)果如下:
[sba, nba, cba, aba]
三、Comparable和Comparator兩個(gè)接口的區(qū)別
Comparable:強(qiáng)行對(duì)實(shí)現(xiàn)它的每個(gè)類的對(duì)象進(jìn)行整體排序。這種排序被稱為類的自然排序,類的compareTo方法被稱為它的自然比較方法。只能在類中實(shí)現(xiàn)compareTo()一次,不能經(jīng)常修改類的代碼實(shí)現(xiàn)自己想要的排序。實(shí)現(xiàn)此接口的對(duì)象列表(和數(shù)組)可以通過(guò)Collections.sort(和Arrays.sort)進(jìn)行自動(dòng)排序,對(duì)象可以用作有序映射中的鍵或有序集合中的元素,無(wú)需指定比較器。
**Comparator:**強(qiáng)行對(duì)某個(gè)對(duì)象進(jìn)行整體排序??梢詫omparator 傳遞給sort方法(如Collections.sort或 Arrays.sort),從而允許在排序順序上實(shí)現(xiàn)精確控制。還可以使用Comparator來(lái)控制某些數(shù)據(jù)結(jié)構(gòu)(如有序set或有序映射)的順序,或者為那些沒(méi)有自然順序的對(duì)象collection提供排序。
四、練習(xí)
創(chuàng)建一個(gè)學(xué)生類,存儲(chǔ)到ArrayList集合中完成指定排序操作。
Student 初始類:
public class Student{ private String name; private int age; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
測(cè)試類:
public class Demo { public static void main(String[] args) { // 創(chuàng)建四個(gè)學(xué)生對(duì)象 存儲(chǔ)到集合中 ArrayList<Student> list = new ArrayList<Student>(); list.add(new Student("rose",18)); list.add(new Student("jack",16)); list.add(new Student("abc",16)); list.add(new Student("ace",17)); list.add(new Student("mark",16)); /* 讓學(xué)生 按照年齡排序 升序 */ // Collections.sort(list);//要求 該list中元素類型 必須實(shí)現(xiàn)比較器Comparable接口 for (Student student : list) { System.out.println(student); } } }
發(fā)現(xiàn),當(dāng)我們調(diào)用Collections.sort()方法的時(shí)候 程序報(bào)錯(cuò)了。 原因:如果想要集合中的元素完成排序,那么必須要實(shí)現(xiàn)比較器Comparable接口。 于是我們就完成了Student類的一個(gè)實(shí)現(xiàn),
如下:
public class Student implements Comparable<Student>{ .... @Override public int compareTo(Student o) { return this.age-o.age;//升序 } }
再次測(cè)試,代碼就OK 了效果如下:
Student{name='jack', age=16}
Student{name='abc', age=16}
Student{name='mark', age=16}
Student{name='ace', age=17}
Student{name='rose', age=18}
五、擴(kuò)展
如果在使用的時(shí)候,想要獨(dú)立的定義規(guī)則去使用 可以采用Collections.sort(List list,Comparetor c)方式,自己定義規(guī)則:
Collections.sort(list, new Comparator<Student>() { @Override public int compare(Student o1, Student o2) { return o2.getAge()-o1.getAge();//以學(xué)生的年齡降序 } });
效果:
Student{name='rose', age=18}
Student{name='ace', age=17}
Student{name='jack', age=16}
Student{name='abc', age=16}
Student{name='mark', age=16}
如果想要規(guī)則更多一些,可以參考下面代碼:
Collections.sort(list, new Comparator<Student>() { @Override public int compare(Student o1, Student o2) { // 年齡降序 int result = o2.getAge()-o1.getAge();//年齡降序 if(result==0){//第一個(gè)規(guī)則判斷完了 下一個(gè)規(guī)則 姓名的首字母 升序 result = o1.getName().charAt(0)-o2.getName().charAt(0); } return result; } });
效果如下:
Student{name='rose', age=18}
Student{name='ace', age=17}
Student{name='abc', age=16}
Student{name='jack', age=16}
Student{name='mark', age=16}
到此這篇關(guān)于java 集合工具類Collections及Comparable和Comparator排序詳解的文章就介紹到這了,更多相關(guān)java Collections 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot讀取resource目錄下文件失敗的原因及解決方案
在idea中運(yùn)行時(shí),有些resource下文件讀取工具類能夠正常獲取讀取到文件,但是通過(guò)java–jar的方式去運(yùn)行jar包,此時(shí)resource下文件讀取工具類讀取文件就失效了,本文就給大家介紹一下SpringBoot讀取resource目錄下文件失敗解決方案,需要的朋友可以參考下2023-08-08JAVA JSP頁(yè)面技術(shù)之EL表達(dá)式整理歸納總結(jié)
這篇文章主要介紹了java中JSP頁(yè)面技術(shù)之EL表達(dá)式概念作用以及語(yǔ)法等的使用,需要的朋友可以參考2017-04-04StringUtils里的isEmpty方法和isBlank方法的區(qū)別詳解
這篇文章主要介紹了StringUtils里的isEmpty方法和isBlank方法的區(qū)別詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2020-04-04Intellij IDEA 配置Subversion插件實(shí)現(xiàn)步驟詳解
這篇文章主要介紹了Intellij IDEA 配置Subversion插件實(shí)現(xiàn)步驟詳解的相關(guān)資料,需要的朋友可以參考下2017-05-05java模板引擎Thymeleaf和前端vue的區(qū)別及說(shuō)明
這篇文章主要介紹了java模板引擎Thymeleaf和前端vue的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11