Java中的Sort排序問題
Java中Sort排序是非常常用的方法,這一章我們主要來認(rèn)識(shí)一下Sort的用法和相關(guān)的實(shí)現(xiàn)。
一、數(shù)組Sort排序
升序排序,直接使用Arrays.Sort方法,例如:
int[] array = {10, 3, 6, 1, 4, 5, 9}; //正序排序 Arrays.sort(array);//會(huì)檢查數(shù)組個(gè)數(shù)大于286且連續(xù)性好就使用歸并排序,若小于47使用插入排序,其余情況使用雙軸快速排序 System.out.println("升序排序:"); for (int num : array) { System.out.println(num); }
降序排序,對(duì)于只輸出數(shù)組的情況,可以倒敘循環(huán)訪問,例如:
//倒序排序 //(1)由于不提供倒排方法,你可以倒敘輸出 System.out.println("降序輸出:"); for (int i = array.length - 1; i >= 0; i--) { System.out.println(array[i]); }
降序排序,對(duì)于需要使用數(shù)組 的情況,可以創(chuàng)建一個(gè)新的數(shù)組,然后倒敘訪問賦值,例如:
//(2)或者創(chuàng)建一個(gè)新的數(shù)組,倒敘保存到新數(shù)組 int[] descArray = new int[array.length]; for (int i = 0; i < array.length; i++) { descArray[i] = array[array.length - i - 1]; } System.out.println("新數(shù)組降序輸出:"); for (int num : descArray) { System.out.println(num); }
降序排序,可以先將數(shù)組轉(zhuǎn)為集合,然后使用Collections.reverse()反轉(zhuǎn)集合,但是對(duì)于非引用類型,不可以使用Arrays.asList(),因?yàn)閕nt[]會(huì)被當(dāng)作一個(gè)類型,而不是數(shù)組。
所以可以使用Guava的Ints.asList()方法實(shí)現(xiàn),該轉(zhuǎn)換后的集合,實(shí)現(xiàn)了List接口的方法,直接將數(shù)組轉(zhuǎn)入內(nèi)部的數(shù)組變量,需要注意它并沒有實(shí)現(xiàn)數(shù)組的操作方法,例如調(diào)用add會(huì)報(bào)錯(cuò):
轉(zhuǎn)換和排序例如:
//(3)或者使用Guava來實(shí)現(xiàn) List<Integer> integersList = Ints.asList(array); Collections.reverse(integersList);//冒泡交換 System.out.println("Guava降序輸出:"); for (int num : integersList) { System.out.println(num); }
轉(zhuǎn)后的集合類是Guava中的IntArrayAsList,其類UML圖如下:
二、集合Sort排序—包裝類
本小節(jié)主要是對(duì)jdk類庫中的包裝類排序,例如:Integer、String等,這些類都已經(jīng)重寫了Compare方法,都有默認(rèn)排序規(guī)則,例如對(duì)于Integer類型會(huì)比較其包裝的值類型大小,對(duì)于String類型會(huì)以長度最小字符串為基準(zhǔn),逐一比較相同位置字符的ASCII碼大小,如果都相同則比較字符串的長度。
以Integer為例子,升序排序:
//Integer集合,正序排序 List<Integer> list = new ArrayList<Integer>(Arrays.asList(10, 3, 6, 1, 4, 5, 9)); Collections.sort(list); System.out.println("集合正序排序:"); for (Integer num : list) { System.out.println(num); }
返回:
集合正序排序: 1 3 4 5 6 9 10
降序排序:
//倒敘排序 Comparator<Integer> reverseComparator = Collections.reverseOrder(); Collections.sort(list, reverseComparator); System.out.println("集合倒敘排序:"); for (Integer num : list) { System.out.println(num); }
返回:
集合倒敘排序: 10 9 6 5 4 3 1
三、集合Sort排序—自定義對(duì)象
除了兩節(jié)所描述的情況,我們還會(huì)遇到對(duì)于自定義類排序的情況,例如我們現(xiàn)在有一個(gè)學(xué)生對(duì)象,想要根據(jù)年齡對(duì)其進(jìn)行排序,學(xué)生類Student如下:
public class Student { private String name; private Integer age; public Student(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } /** * 為了更好顯示數(shù)據(jù),我們重寫toString()方法. * @return 顯示變量的字符串 */ @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
(1) 第一種方式,是實(shí)現(xiàn)Comparable接口,重寫接口方法。
該CompareTo()方法,如果指定的數(shù)與參數(shù)相等返回0;如果指定的數(shù)小于參數(shù)返回 -1;如果指定的數(shù)大于參數(shù)返回 1。
對(duì)于排序來講,你可以認(rèn)為當(dāng)返回1時(shí),指定的數(shù)和參數(shù)會(huì)進(jìn)行交換,而非1時(shí)則不變,指定數(shù)可以當(dāng)作原本的數(shù)組中靠前的數(shù),而參數(shù)可以當(dāng)作靠后的數(shù),又因?yàn)橹挥锌壳皵?shù)大于靠后數(shù)時(shí)才返回1,所以大的會(huì)被放到后面,此時(shí)升序排序(方便記憶)。以此類推,倒序情況則相反。
升序排序,比Student類增加了Comparable接口,并實(shí)現(xiàn)升序排序:
public class StudentAsc implements Comparable<StudentAsc> { private String name; private Integer age; public StudentAsc(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public int compareTo(StudentAsc o) { if(null == this.age) { return -1; } if(null == o.getAge()) { return 1; } return this.age.compareTo(o.getAge()); } @Override public String toString() { return "StudentAsc{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
方法調(diào)用:
//正序排序,年齡為null時(shí)為小 StudentAsc studentWang = new StudentAsc("王小二", 10); StudentAsc studentZhang = new StudentAsc("張三", 1); StudentAsc studentGou = new StudentAsc("狗子", 99); StudentAsc studentZhao = new StudentAsc("趙六", 40); StudentAsc studentLi = new StudentAsc("李四", null); List<StudentAsc> studentAscs = new ArrayList<StudentAsc>(Arrays.asList(studentWang, studentZhang, studentGou, studentZhao, studentLi)); Collections.sort(studentAscs); System.out.println("自定義對(duì)象,升序排序:"); for(StudentAsc studentAsc : studentAscs) { System.out.println(studentAsc.toString()); }
返回:
自定義對(duì)象,升序排序: Student{name='李四', age=null} Student{name='張三', age=1} Student{name='王小二', age=10} Student{name='趙六', age=40} Student{name='狗子', age=99}
降序排序,比Student類增加了Comparable接口,并實(shí)現(xiàn)倒序排序:
public class StudentDesc implements Comparable<StudentDesc> { private String name; private Integer age; public StudentDesc(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public int compare(Integer o1, Integer o2) { return o2.compareTo(o1); } public int compareTo(StudentDesc o) { if(null == this.age) { return 1; } if(null == o.getAge()) { return -1; } return o.age.compareTo(this.getAge()); } @Override public String toString() { return "StudentDesc{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
方法調(diào)用:
//降敘排序,年齡為null時(shí)為最大 StudentDesc studentWang = new StudentDesc("王小二", 10); StudentDesc studentZhang = new StudentDesc("張三", 1); StudentDesc studentGou = new StudentDesc("狗子", 99); StudentDesc studentZhao = new StudentDesc("趙六", 40); StudentDesc studentLi = new StudentDesc("李四", null); List<StudentDesc> studentAscs = new ArrayList<StudentDesc>(Arrays.asList(studentWang, studentZhang, studentGou, studentZhao, studentLi)); Collections.sort(studentAscs); System.out.println("自定義對(duì)象,降序排序:"); for(StudentDesc studentAsc : studentAscs) { System.out.println(studentAsc.toString()); }
返回:
自定義對(duì)象,降序排序: Student{name='狗子', age=99} Student{name='趙六', age=40} Student{name='王小二', age=10} Student{name='張三', age=1} Student{name='李四', age=null}
(2)第二種方式,上面實(shí)現(xiàn)Comparable接口的方法并不十分靈活,比如對(duì)于一個(gè)類,在不同的地方需要使用不同的排序,此時(shí)再這樣做就會(huì)顯的十分繁瑣。因此我們可以通過Collections.sort(List<T> list, Comparator<? super T> c)方法來實(shí)現(xiàn),例子中,我們使用Student類,例子如下:
升序排序:
//升序排序 Student studentWang = new Student("王小二", 10); Student studentZhang = new Student("張三", 1); Student studentGou = new Student("狗子", 99); Student studentZhao = new Student("趙六", 40); Student studentLi = new Student("李四", null); List<Student> students = new ArrayList<Student>(Arrays.asList(studentWang, studentZhang, studentGou, studentZhao, studentLi)); Collections.sort(students, new Comparator<Student>() { public int compare(Student o1, Student o2) { if(null == o1.getAge()) { return -1; } if(null == o2.getAge()) { return 1; } return o1.getAge().compareTo(o2.getAge()); } }); System.out.println("自定義對(duì)象,升序排序:"); for(Student student : students) { System.out.println(student.toString()); }
返回:
自定義對(duì)象,升序排序: Student{name='李四', age=null} Student{name='張三', age=1} Student{name='王小二', age=10} Student{name='趙六', age=40} Student{name='狗子', age=99}
降序排序:
//降序排序 Student studentWang = new Student("王小二", 10); Student studentZhang = new Student("張三", 1); Student studentGou = new Student("狗子", 99); Student studentZhao = new Student("趙六", 40); Student studentLi = new Student("李四", null); List<Student> students = new ArrayList<Student>(Arrays.asList(studentWang, studentZhang, studentGou, studentZhao, studentLi)); Collections.sort(students, new Comparator<Student>() { public int compare(Student o1, Student o2) { if(null == o1.getAge()) { return 1; } if(null == o2.getAge()) { return -1; } return o2.getAge().compareTo(o1.getAge()); } }); System.out.println("自定義對(duì)象,降序排序:"); for(Student student : students) { System.out.println(student.toString()); }
返回:
自定義對(duì)象,降序排序: Student{name='狗子', age=99} Student{name='趙六', age=40} Student{name='王小二', age=10} Student{name='張三', age=1} Student{name='李四', age=null}
總結(jié)
至此對(duì)數(shù)組、包裝類集合、自定義集合排序做了總結(jié)。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java實(shí)現(xiàn)銀行ATM系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)銀行ATM系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04Java中ScheduledExecutorService介紹和使用案例(推薦)
ScheduledExecutorService是Java并發(fā)包中的接口,用于安排任務(wù)在給定延遲后運(yùn)行或定期執(zhí)行,它繼承自ExecutorService,具有線程池特性,可復(fù)用線程,提高效率,本文主要介紹java中的ScheduledExecutorService介紹和使用案例,感興趣的朋友一起看看吧2024-10-10SpringBoot中@ConfigurationProperties自動(dòng)獲取配置參數(shù)的流程步驟
當(dāng)需要獲取配置文件中很多參數(shù)時(shí),我們可以定義參數(shù)的前綴相同,通過自動(dòng)映射 進(jìn)行獲取配置文件中參數(shù),所以本文給大家介紹了SpringBoot中@ConfigurationProperties自動(dòng)獲取配置參數(shù)的流程步驟,需要的朋友可以參考下2024-11-11簡單的一次springMVC路由跳轉(zhuǎn)實(shí)現(xiàn)
本文主要介紹了springMVC路由跳轉(zhuǎn)實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04maven父工程relativepath標(biāo)簽使用解讀
文章主要介紹了在使用Maven構(gòu)建父子工程時(shí)如何通過設(shè)置父工程和子工程的pom文件來管理依賴和版本,當(dāng)子工程是Spring Boot項(xiàng)目時(shí),可以通過關(guān)閉`relativePath`標(biāo)簽來繼承Spring Boot的父工程,同時(shí)在父工程中使用`dependencyManagement`標(biāo)簽來統(tǒng)一管理Spring Boot的依賴版本2024-11-11