溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

Java中Collections.sort對(duì)List排序的方法有哪些

發(fā)布時(shí)間:2021-12-03 11:30:41 來(lái)源:億速云 閱讀:175 作者:iii 欄目:開(kāi)發(fā)技術(shù)

本篇內(nèi)容介紹了“Java中Collections.sort對(duì)List排序的方法有哪些”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

一、Collections.sort的簡(jiǎn)單使用

說(shuō)到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

可見(jiàn),實(shí)現(xiàn)了對(duì)List<String>的排序,非常簡(jiǎn)單。

二、問(wèn)題提出

但在我們的項(xiàng)目中列表List的元素類(lèi)型經(jīng)常是自定義的,下面自定義了一個(gè)實(shí)體類(lèi)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)行排序,首先想到的也是通過(guò)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ù)類(lèi)型,而應(yīng)該extends Comparable。為什么?
原來(lái),要排序嘛當(dāng)然要有排序的規(guī)則,比如按身高從高到低,按年齡從小到大,等等,也就是要有比較。而String這個(gè)對(duì)象已經(jīng)幫我們實(shí)現(xiàn)了Comparable接口,所以String類(lèi)型自己就是可以比較的。而我們的Person如果想要排序,也必須能夠按某種規(guī)則進(jìn)行比較,也就是要實(shí)現(xiàn)一個(gè)比較器。我們可以通過(guò)實(shí)現(xiàn)Comparable或Comparator接口實(shí)現(xiàn)比較器 。

三、Comparable實(shí)現(xiàn)排序

Comparable實(shí)現(xiàn)比較器,是定義在Person類(lèi)的內(nèi)部的,所以實(shí)體類(lèi)Person需要implements Comparable<Person>,然后重寫(xiě)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類(lèi)的外部的,因此實(shí)體類(lèi)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的接口,用來(lái)對(duì)自定義的實(shí)體對(duì)象進(jìn)行比較;

2)Comparable 是定義在實(shí)體類(lèi)內(nèi)部的,所以實(shí)體類(lèi)對(duì)象本身就有比較大小的可能。但如果想換一種比較規(guī)則,如先按年齡后按名字排序,那么就必須修改實(shí)體類(lèi)Person本身;

3)Comparator是在實(shí)體類(lèi)外部實(shí)現(xiàn)比較器的,所以對(duì)List排序時(shí)必須同時(shí)傳入數(shù)據(jù)和比較器,如Collections.sort(list, new MyComparator());如果想換一種比較規(guī)則,則僅需要修改比較器MyComparator,而實(shí)體類(lèi)Person則不需要改變;所以建議使用這種方法;

4)Comparable實(shí)現(xiàn)代碼相對(duì)簡(jiǎn)單,Comparator實(shí)現(xiàn)代碼相對(duì)復(fù)雜一點(diǎn),但還是建議使用Comparator方法。

“Java中Collections.sort對(duì)List排序的方法有哪些”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI