對對象數組與存放對象數據的集合進行排序 —— Comparable接口的用法

Arrays類的sort方法能夠對整型數組進行升序排列:java

int[] i = { 1, 5, 2, 4, 3 };
Arrays.sort(i);
System.out.println(Arrays.toString(i));

控制檯則輸出:[1, 2, 3, 4, 5]算法

Collections類的sort方法能夠對整型數據集合實現相同的功能:數組

List<Integer> l = new ArrayList<>();
l.add(1);
l.add(5);
l.add(2);
l.add(4);
l.add(3);
Collections.sort(l);
System.out.println(l);

輸出爲:[1, 2, 3, 4, 5]ide


其實,sort方法不單單能夠對整型數據進行排序,也能夠對對象數組與存放對象數據的集合進行排序,並且能夠指定排序方式(升序或降序),但要求知足如下前提:對象所屬的類必須實現了Comparable接口。工具

下面是Comparable接口的源代碼:測試

public interface Comparable<T> {
    public int compareTo(T o);
}

在實現接口時,泛型<T>中的T需聲明爲欲排序對象的類型。this

若一個數組或集合中存放的對象所對應的類實現了Comparable接口並重寫了compareTo方法,那麼在調用Arrays.sort或Collections.sort的時候就可以對數組或集合進行排序。具體實現的方式咱們在這裏不去討論,由於那是Arrays類和Collections類中的內容(這兩個類分別爲對數組和集合進行相關操做的工具類,好比排序功能的實現),在這裏咱們着重探討一下Comparable接口中的comparaTo抽象方法。code

在調用s.compareTo(o)的時候,compareTo方法會比較兩個對象的內容,並返回比較的結果。當s小於o時,返回一個負數;當s大於o時,返回一個正數;不然(s等於o)時,返回0。對象

所以,在實現類重寫compareTo方法時,須要比較當前類中的屬性(好比,年齡 age)與參數對象o對應屬性(o.age)的大小,並根據需求(升序排列、降序排列)返回相應的值(正數或負數)。排序

這段話苦澀難懂,不過不用擔憂,接下來的例子會讓你很輕鬆的理解它想表達的意思。


現有一簡單的學生類 Student,類中包含學生的一些信息:姓名 name、年齡 age,包含構造方法對學生信息進行初始化,重寫toString方法用來在控制檯打印信息。代碼以下:

public class Student {

	private String name;
	private int age;

	public Student(String name, int age) {
		this.name = name;
		this.age = age;
	}

	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}

}

建立一測試類,實例化5個學生,並存入Student類型的數組。代碼以下:

public class Test {

	public static void main(String[] args) {

		Student s1 = new Student("張三", 20);
		Student s2 = new Student("李四", 18);
		Student s3 = new Student("王五", 22);
		Student s4 = new Student("趙六", 19);
		Student s5 = new Student("孫七", 21);

		Student[] s = { s1, s2, s3, s4, s5 };

	}

}

現有需求:將數組中的學生按照年齡進行升序排列。

此時,便須要用到Arrays.sort方法。但前文已經說過,對對象數組進行排序須要對象所屬類實現Comparable接口並重寫compareTo方法。所以咱們須要對Student類進行以下修改:

實現Comparable接口:

public class Student implements Comparable<Student> {     // 泛型T改成欲排序的對象所屬的類(Student)

重寫compareTo方法:

@Override
public int compareTo(Student o) {
	if (age < o.age) {
		return -1;     // 這裏的-1能夠改爲任意負數,若想按降序排列則改成返回一個正數
	} else if (age > o.age) {
		return 1;     // 若想按降序排列則改成返回一個負數
	} else {
		return 0;
	}
}

其實這個方法有改善的空間,Integer類有一個名爲compare的靜態方法,源代碼以下:

public static int compare(int x, int y) {
    return (x < y) ? -1 : ((x == y) ? 0 : 1);
}

方法體中的三元表達式的做用爲:當 x < y 時,返回 -1;當 x > y 時,返回 1;不然返回 0。這正是咱們所須要的。順便一提,Double類也有這個方法,它能適用於double類型的數據,適用面更廣。

修改後的compateTo方法:

@Override
public int compareTo(Student o) {
	return Integer.compare(age, o.age);
}

怎麼樣,是否是簡化了不少?若想按降序排列只要改變compare方法兩個參數的位置就能夠了(age 和 o.age)。

如今咱們能夠在Test類中調用sort方法,並用foreach循環將排序後的數組打印出來了:

Arrays.sort(s);
for (Student ss : s)
	System.out.println(ss);     // 這裏可以直接輸出Student的對象是由於Student類中重寫了toString方法

打印結果爲:

Student [name=李四, age=18]
Student [name=趙六, age=19]
Student [name=張三, age=20]
Student [name=孫七, age=21]
Student [name=王五, age=22]

至此,咱們已經實現了對對象數組的排序操做。


若想對存放對象數據的集合進行排序須要執行的操做是相似的,只要將對象存到集合就能夠了。

不過這裏須要注意的是,TreeSet集合自己便具備排序的功能,所以,若是一個TreeSet中存放的對象數據所對應的類沒有實現Comparable接口,那麼在對這個TreeSet進行操做的時候會拋出一個ClassCastException(類型轉換異常),它會提示你存放的數據沒法轉換成Comparable類型。


在本文中,咱們進行排序操做時均選擇了整型的數據,好比整型數組和整型數據集合,對對象數組的排序也選擇了以整型的年齡做爲判斷的依據。其實,sort方法的排序依據不單單侷限於整型,只要制定好排序的規則,即可以按照需求作出相應的排序操做,好比按照姓名的首字母進行排序等,這些更復雜的需求須要咱們對sort方法進行深刻的研究,也須要在重寫compareTo方法時給出更復雜的算法。若是你有興趣,能夠去嘗試一下,相信你必定會成功!


在本文的最後我會放上Student類和Test類的所有代碼,供參考用。

若是您看到了這裏,我表示由衷的感謝,這是個人第一篇博文,但願您之後能多多支持!


Student:

public class Student implements Comparable<Student> {

	private String name;
	private int age;

	public Student(String name, int age) {
		this.name = name;
		this.age = age;
	}

	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}

	@Override
	public int compareTo(Student o) {
		return Integer.compare(age, o.age);
	}

}

Test:

import java.util.Arrays;

public class Test {

	public static void main(String[] args) {

		Student s1 = new Student("張三", 20);
		Student s2 = new Student("李四", 18);
		Student s3 = new Student("王五", 22);
		Student s4 = new Student("趙六", 19);
		Student s5 = new Student("孫七", 21);

		Student[] s = { s1, s2, s3, s4, s5 };

		Arrays.sort(s);
		for (Student ss : s)
			System.out.println(ss);

	}

}

感謝閱讀!

相關文章
相關標籤/搜索