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)行整體排序。可以將Comparator 傳遞給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-08
JAVA JSP頁(yè)面技術(shù)之EL表達(dá)式整理歸納總結(jié)
這篇文章主要介紹了java中JSP頁(yè)面技術(shù)之EL表達(dá)式概念作用以及語(yǔ)法等的使用,需要的朋友可以參考2017-04-04
StringUtils里的isEmpty方法和isBlank方法的區(qū)別詳解
這篇文章主要介紹了StringUtils里的isEmpty方法和isBlank方法的區(qū)別詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2020-04-04
Intellij IDEA 配置Subversion插件實(shí)現(xiàn)步驟詳解
這篇文章主要介紹了Intellij IDEA 配置Subversion插件實(shí)現(xiàn)步驟詳解的相關(guān)資料,需要的朋友可以參考下2017-05-05
java模板引擎Thymeleaf和前端vue的區(qū)別及說(shuō)明
這篇文章主要介紹了java模板引擎Thymeleaf和前端vue的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11

