本節書摘來自異步社群《android遊戲開發詳解》一書中的第2章,第2.21節對象和基本類型的分組,作者 【美】jonathan s. harbour,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視
2.21 對象和基本類型的分組
android遊戲開發詳解
java允許我們把對象和基本類型組織到一起。我們常見的有兩種對象,可以用來進行分組,它們是數組和清單。
2.21.1 數組
要表示某種類型的一個數組(或組),我們使用方括号。例如,如果想要整數的一個數組,可以像下面這樣聲明。
上面例子中的數字5,表示名為numbers的數組應該有多大。正如上面所聲明的,numbers将能夠容納5個整數值。要描述數組的樣子,我們可以畫一個表,如圖2-28所示。

一開始,數組将會有預設值(建立整數數組的時候,預設值是0)。java允許我們直接為每個索引(或位置)配置設定數值。數組索引是基于0的,就像字元串中的字元一樣。數組的指派文法如下所示。
numbers數組将會如圖2-29所示。
我們可以使用完全相同的文法來擷取這些值。舉例如下。
數組也有缺點。一旦建立了數組,就不能改變其大小。為什麼會有這個問題呢?想象一下,你在開發一個射擊遊戲,其中每次玩家點選滑鼠左鍵,就會有一個bullet對象添加到一個數組中(表示所有已經發射的子彈)。我們事先不知道需要多少個bullet。某些玩家可能使用42顆子彈。其他的玩家可能使用刀和手榴彈,甚至不開一槍就完成了關卡。在這種情況下,使用arraylist通常會更好,它允許我們動态地調整大小以放入更多的對象。
2.21.2 arraylists
arraylists比數組更加常用,并且你應該知道如何使用它們(以及如何用好它們)。要使用arraylist,必須首先導入它。
我們從somearraylist提取出第153個對象(記住,索引是基于0的)。問題在于,我們對這個對象一無所知。它可能是一個可口的sushi對象,又或者甚至是一個危險的bomb。如果我們這樣編寫代碼,想象一下後果。
實際上,java允許我們通過添加标志,來限制arraylists隻儲存某一種類型的對象。
現在,我們知道從playernames擷取的任何對象都是一個string,并且我們可以在其上調用string方法。
2.21.3 對基本類型使用arraylist
不能直接将基本資料類型插入到一個arraylist中。實際上,如下所示的代碼是不允許的。
要繞開這個限制,可以直接使用一個内建的包裝類,即每種基本資料類型的對象版本。這包括int所對應的integer,char所對應的character,等等。要做到這點,直接建立該arraylist并聲明包裝類作為其類型。
這個arraylist最初的大小為0。
接下來,直接調用add()方法,并且傳入想要放到arraylist中的int值。這些值将會自動地包裝到一個integer對象中。
此時,arraylist看上去如圖2-30所示(注意,其長度動态地增長了)。
你可以調用get()方法,傳入想要的值的索引,進而擷取基本類型值。例如,要取回數字3,讓arraylist給出位于索引1的值。這個值會自動轉換為一個int(從包裝的integer對象),是以,你可以将它存儲到一個int變量中。
``
int mynum = numbers.get(1);
system.out.println(mynum); // prints 3
01 public class listtester {
02
03 public static void main(string[] args) {
04
05 }
06
07 }
01 public class person {
02
03 private string name;
04 private int age;
05
06 public void initialize(string name, int age) {
07 this.name = name;
08 this.age = age;
09 }
10
11 public void describe() {
12 system.out.println("my name is " + name);
13 system.out.println("i am " + age + " years old");
14 }
15
16 }
person類描述了一個新的person對象的藍圖。特别是,它表明了一個person對象的狀态将由兩個執行個體變量來描述,即name和age。我們沒有給name和age預設值,并且,必須調用initialize()方法來提供這些值。一旦person對象有了一個name和age,我們就可以調用describe()方法,以易于了解、可讀的形式列印出這些資訊。讓我們回到listtester并且確定可以做到這一點。
程式清單2.27 listtester.java(更新版本)
我們來一行一行地看一看程式清單2.27:首先建立了person類的一個名為p的新執行個體。此時,p有兩個執行個體變量:name和age。這些變量還沒有初始化。
接下來,我們調用了initialize()方法,它接受兩個值:一個string和一個整數。initialize()方法将會接受這兩個值,并且将其指派給執行個體變量。
現在,兩個執行個體變量已經初始化了,我們可以通過調用describe()來要求person對象描述自己。結果如下所示。
現在,我們建立多個person對象并且将它們組織到一個arraylist中。修改listtester類,使其如程式清單2.28所示。
程式清單2.28 建立arraylist并添加第一個循環
在程式清單2.28中,我們建立了一個新的、名為people的arraylist,以及一個新的名為r的random對象。然後,開始了一個for循環,它将運作5次。循環每疊代(重複)一次,我們就建立一個名為p的新的person對象。用相應的名稱(person #i,其中i從0到4)和一個随機生成的年齡值,來為該person初始化執行個體變量。最後,我們把新建立的person對象添加到arraylist中(第14行)。循環重複,建立了一個全新的person,初始化它并且再次添加它。
注意如下所示的代碼行。
在循環中建立的任何變量,都隻在其相同的疊代中有效,這意味着,該變量僅限于在循環的目前疊代中存在。是以,我們可以在循環的每一次重複中複用變量名p。
每次調用上面的代碼,我們都用變量名p建立了一個新的person。然後,将臨時變量p中儲存的值,存儲到較為持久的、名為people的arraylist中,以便随後在代碼中可以引用每一個新建立的person對象,而不需要為它們中的每一個配置設定一個唯一的變量名。
為了看到這是如何工作的,我們可以嘗試再次疊代循環,并且調用describe()方法,如程式清單2.29所示(第17行到第20行)。
程式清單2.29 添加第2個循環
最終的輸出如下所示(年齡可能不同,因為是随機生成的)。
你可能會問,為什麼要将第17行到第20行的循環運作people.size()次而不是5次?兩個值是相同的,并且任何一個解決方案都會産生相同的輸出;然而,上面的例子是一個更加靈活的循環,因為它并不需要把循環運作的次數直接編碼。根據arraylist people的大小,第二個for循環将運作相應的次數。這意味着,我們可能需要将上一個循環(即向arraylist添加對象的那個循環)運作的次數從5修改為8,而下面的循環則不需要修改,因為people.size()也會增加為8。
程式清單2.30 疊代8次
最終輸出如下所示(年齡可能不同,因為是随機生成的)。
上面的示例展示了如何使用循環快速地建立多個對象,并将它們組織到一個arraylist中。我們還學習到,可以通過一個for循環快速周遊一個arraylist的所有成員并調用其方法。