【java基礎(二十八)】泛型數組列表

在許多程序設計語言中,必須在編譯時就確定整個數組的大小。程序員對此十分反感,因爲這樣做將迫使程序員做出一些不情願的這種。例如,一個部門中有多少僱員?肯定不會超過100人?一旦出現一個擁有150名僱員的大型部門呢?願意爲那些僅有10名僱員的部門浪費90名僱員佔據的存儲空間嗎?
在Java中,情況就好一些。它允許在運行時確定數組的大小。

int actualSize = ...;
Employee[] staff = new Employee[actualSize];

當然,這段代碼並沒有完全解決運行時動態改變數組的問題。一旦確定了數組的大小,改變它就不太容易了。在Java中,解決這個問題最簡單的方法是使用Java中另外一個被稱爲ArrayList的類。它使用起來有點像數組,但在添加或刪除元素時,具有自動調節數組容量功能,而不需要爲此編寫任何代碼。
ArrayList是一個採用類型參數(type parameter)的泛型類(generic class)。爲了指定數組列表保存的元素對象類型,需要用一堆尖括號將類名括起來加在後面,例如,ArrayLis<Employee>。下面看如何聲明和構造一個保存Employee對象的數組列表:

ArrayList<Employee> staff = new ArrayList<Employee>();

兩邊都使用類型參數Employee,有些繁瑣,在JavaSE7中,可以省去右邊的類型參數:

ArrayList<Employee> staff = new ArrayList<>();

這被稱爲“菱形”語法,因爲空尖括號<>就像是一個菱形。可以結合new操作符使用菱形語法。編譯器會檢查新值是什麼。如果賦值給一個變量,或傳遞給某個方法,或者從某個方法返回,編譯器會檢查這個變量、參數或方法的泛型類型,然後將這個類型放在<>中。在這個例子中,new ArrayList<>()將賦值一個類型爲ArrayList<Employee>的變量,所以泛型類型爲Employee。
使用add方法可以將元素添加到數組列表中。例如,下面展示瞭如何將僱員對象添加到數組列表中的方法:

staff.add(new Employee("Harry Hacker", ...));
staff.add(new Employee("Tony Tester", ...));

數組列表管理着對象引用的一個內部數組。最終,數組的全部空間有可能被用盡。這就顯現出數組列表的操作魅力:如果調用add且內部數組已經滿了,數組列表將自動地創建一個更大的數組,並將所有的對象從較小的數組中拷貝較大的數組中。
如果已經清楚或能夠估計出數組可能存儲的元素數量,就可以在填充數組之前調用ensureCapacity方法:

staff.ensureCapacity(100);

這個方法調用將分配一個包含100個對象的內部數組。然後調用100次add,而不用重新分配空間。
另外,還可以把初始容量傳遞給ArrayList構造器:

ArrayList<Employee> staff = new ArrayList<>(100);

size方法將返回數組列表中包含的實際元素數目。例如:

staff.size()

將返回staff數組列表的當前元素數量,它等價於數組a的a.length。
一旦能夠確認數組列表的大小不再發生變化,就可以調用trimToSize方法。這個方法將存儲區域的大小調整爲當前元素數量所需要的存儲空間數目。垃圾回收器將回收多餘的存儲空間。
一旦整理了數組列表的大小,添加新元素就需要花時間在此移動存儲塊,所以應該在確認不會添加任何元素時,再調用trimToSize。

訪問數組列表元素

很遺憾,天下沒有免費的午餐。數組列表自動擴展容量的便利增加了訪問元素語法的複雜程度。起原因是ArrayList類並不是Java程序設計語言的一部分;它只是一個由某些人編寫且放在標準庫中的一個實用類。
使用get和set方法實現訪問或改變數組元素的操作,而不使用人們喜愛的[]語法格式。
例如,要設置第i個元素,可以使用:

staff.set(i, harry);

它等價於對數組a的元素賦值(數組的下標從0開始):

a[i] = harry;

使用下列格式獲得數組列表的元素:

Employee e = staff.get(i);

等價於:

Employee e = a[i];

下面這個技巧可以一舉兩得,即可以靈活地擴展數組,又可以方便地訪問數組元素。首先,創建一個數組,並添加所有的元素:

ArrayList<X> list = new ArrayList<>();
while (...) {
	x = ...;
	list.add(x);
}

執行完上述操作後,使用toArray方法將數組元素拷貝到一個數組中。

x[] a = new X[list.size()];
list.toArray(a);

除了在數組列表的尾部追加元素之外,還可以在數據列表的中間插入元素,使用帶索引參數的add方法。

int n = staff.size() / 2;
staff.add(n, e);

爲了插入一個新元素,位於n之後的所有元素都要向後移動一個位置。如果插入新元素後,數組列表的大小超過了容量,數組列表就會被重新分配存儲空間。
同樣地,可以從數組列表中間刪除一個元素。

Employee e = staff.remove(n);

位於這個位置之後的所有元素都向前移動一個位置,並且數組的大小減1。
對數組實施插入和刪除元素的操作其效率比較低。對於小型數組來說,這一點不必擔心,但如果數組存儲的元素數比較多,又經常需要在中間位置插入、刪除元素,就應該考慮使用鏈表了。
可以使用for … each 循環遍歷數據列表。

實例

package cn.freedompc.arraylist;

import java.util.ArrayList;

import cn.freedompc.equals.Employee;

public class ArrayListTest {

	public static void main(String[] args) {
		ArrayList<Employee> staff = new ArrayList<>();

		staff.add(new Employee("Carl Cracker", 75000, 1987, 12, 15));
		staff.add(new Employee("Harry Hacker", 50000, 1989, 10, 1));
		staff.add(new Employee("Tony Tester", 40000, 1990, 3, 15));
		
		for (Employee e : staff)
			System.out.println("name=" + e.getName() + ",salary=" + e.getSalary() + ","
					+ "hireDay=" + e.getHireDay());
	}
	
}

結果

在這裏插入圖片描述

捐贈

若你感覺讀到這篇文章對你有啓發,能引起你的思考。請不要吝嗇你的錢包,你的任何打賞或者捐贈都是對我莫大的鼓勵。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章