Java中對集合進行排序的兩種方法:
java集合的工具類Collections中提供了兩種排序的方法,分別是:
- Collections.sort(List list)
- Collections.sort(List list,Comparator c)
1)第一種稱為自然排序:
參與排序的對象需實現comparable接口(注:Interger和String不需要,java默認封裝這個兩個類實現了comparable接口),重寫其compareTo()方法,方法體中實現對象的比較大小規則,示例如下:
package test; public class Emp implements Comparable { private String name; private int 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; } public Emp() { super(); } public Emp(String name, int age) { super(); this.name = name; this.age = age; } @Override public String toString() { return "Emp [name=" + name + ", age=" + age + "]"; } @Override public int compareTo(Emp emp) {
// return this.age-emp.getAge();//按照年齡升序排序 return this.name.compareTo(emp.getName());//換姓名升序排序
}
}
@Test //測試 public void testComparable(){ List list = new ArrayList(); list.add(new Emp(18, "tom")); list.add(new Emp(20,"jack")); list.add(new Emp(15,"rose")); list.add(new Emp(17,"jerry")); System.out.println("排序前:"); for(Emp o : list){ System.out.println(o); } Collections.sort(list); System.out.println("自然排序按age排序后:"); for(Emp o : list) { System.out.println(o); } }
輸出結果:
分析:第一種方法不夠靈活,要求實體類(集合元素)必須實現comparable接口,並且定義比較規則,這樣導致會增加耦合,不利於程序的擴展;如果在項目中不同的位置需要根據不同的屬性調用排序方法時,需要反復修改比較規則(按name還是按age),二者只能選擇其一,會起沖突,所以不建議使用這個構造方法。第二種就很好地解決了這個問題,在需要的地方,創建個內部類的實例,重寫其比較方法即可。
2)第二種叫自定義排序:
方法一:自定義一個Comparator比較器對象,然后傳入Collections.sort(List,Comparator)排序方法中進行排序自定義的比較器:
bean(實體類--集合元素):
public class Emp{ private int age; private String name; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Emp(int age, String name) { this.age = age; this.name = name; } @Override public String toString() { return "Emp{" + "age=" + age + ", name='" + name + '\'' + '}'; } }
測試代碼如下:
import java.util.Comparator; public class MyComparator implements Comparator<Emp>{ @Override public int compare(Emp o1, Emp o2) { return o1.getAge()-o2.getAge();//根據傳入的Emp的年齡age由小到大進行升序排序 } } 測試類: @Test public void testComparatorSortAge(){ List list = new ArrayList(); list.add(new Emp(18, "tom")); list.add(new Emp(20,"jack")); list.add(new Emp(15,"rose")); list.add(new Emp(17,"jerry")); System.out.println("排序前:"); for(Emp o : list){ System.out.println(o); } Collections.sort(list,MyComparator);
System.out.println("使用Comparator比較器自定義按age升序排序后:");
for(Emp o : list){
System.out.println(o);
}
}
輸出結果:
方法二:采用匿名內部的形式(推薦做法):
先new一個Comparator接口的比較器對象,同時實現compare()其方法;然后將比較器對象傳給Collections.sort()方法的參數列表中,實現排序功能。
@Test public void testComparatorSortName(){ List list = new ArrayList(); list.add(new Emp(18, "tom")); list.add(new Emp(20,"jack")); list.add(new Emp(15,"rose")); list.add(new Emp(17,"jerry")); System.out.println("排序前:"); for(Emp o : list){ System.out.println(o); } Collections.sort(list, new Comparator() { @Override public int compare(Emp o1, Emp o2) { return o1.getName.compareTo(o2.getName); } }); System.out.println("使用Comparator比較器自定義按name升序排序后:"); for(Emp o : list){ System.out.println(o); } }
輸出結果:
注:默認根據英文首字母大小比較排序,若首字母相同,則比較第二位字母大小,以此類推。
比較總結:
1.對於集合比較使用Collections.sort();
2.對於集合中的對象比較,需要指定比較邏輯,指定比較邏輯需要實現 Comparable接口並重寫compareTo方法自定義邏輯。
3.對於需要臨時改變比較規則,例如項目中存在多個場景調用不同的排序規則的情況時,需要使用Collections.sort(List,Comparator),采用回調方式重寫Comparator接口的compare方法自定義邏輯。
參考文章:
1.https://blog.csdn.net/qq_43437465/article/details/89437637