AS3.0 Vector的運用


使用Vector類編程

一個array(數組)就像是把一套變量組織在一起的容器。單個數組可以含有許多不同的值。你可以儲存和取得數組中的單個值(也就是數組elements(元素))。你也可以通過直接操作數組變量來成組地使用其值。最常見的是有序數組。你可以憑某個索引號從中獲取值。Action Script3包括了用於索引數組的兩個類。

  • Array 類:一個可以包含各種值類型的索引數組,其包容度甚至可以允許你在同一個數組里混合各種值類型。
  • Vector類:也是索引數組。其元素必須都為同一個類的實例。Vector類適用於 Flash Player 10和之后的版本。

如果你需要存儲一系列具有相同數據類型的值,與Array類相比,Vector類有一些優勢。首先,因為Vector的所有元素要求必須有相同的數據類型,所以ActionScript編譯器在代碼編譯的時候就可以進行類型檢查。任意嘗試添加或恢復錯誤類型值的代碼都將被處理為編譯時錯誤。數據類型在運行時也會進行檢查,因此,假設數據類型不能再編譯時被檢查出來,它仍然會被檢查,而且數據類型限制也還是有效的。除了類型檢查的優點之外,使用Vector類的代碼比使用Array創建的同樣代碼明顯運行得要快— —這是一個重要的優勢。

這篇快速入門描述了創建於使用Vector類的技巧。要了解更多關於Array類的使用,請參考Flash快速入門使用數組編程

以下段落描述了使用Vector對象的常用接下來的部分描述了用Vector對象完成一般任務:創建一個Vector實例,為一個Vector對象添加值,為一個Vector對象更改值,為一個Vector對象的值分類。

基本要求

要實現這篇快速入門中的實例,你需要如下實例文件:

示例文件

這個示例存檔文件包含了如下幾個文件:

  • SortVectorOfNumber.fla:一個Flash文件,演示了在Vector中對數字值進行排序,在本文中的"將一個Vector中的值進行排序"分段中進行描述。
  • SortVectorOfObject.fla:一個示例演示中Vector中對常用對象進行排序,在本文中的"將一個Vector中的值進行排序"分段中進行描述。
  • Person.as:Person類的源碼,在SortVectorOfObject.fla中引用。

要測試每個應用,請打開FLA文件,並選擇"控制 > 測試影片"。

預備知識

推薦有使用ActionScript3編程的一般經驗。

創建一個Vector實例

一個Vector對象是一個只保存着某類值的索引數組。Vector對象特定保存的類是Vector的基本型。而調用Vector類的構造函數的時候就創建了一個Vector對象。你也許猜到了,制定給Vector變量的基本類必須匹配調用構造函數時指定的基本型。

當創建一個Vector實例的時候,為了指定它的基本型,你要在Vector類名字上增加額外的信息, 使用一個叫做類型參數的語法格式。比如,下面的表述聲明了一個叫做myVector的Vector變量,使用類型參數語法來指出在myVector里的 Vector只能包含字符串類型的值。

var myVector:Vector.<String>;

當你調用Vector構造函數來實際創建Vector對象的時候可以用一樣的語法:

myVector = new Vector.<String>();

作為一種規則,只要有Vector這個類名出現在你的代碼里,你總是要對它使用一個類型參數。

當然,你可以把變量聲明和構造實例整合到一行代碼里。

var myVector:Vector.<String> = new Vector.<String>();

盡管在這篇快速入門中所給的示例都比較簡單,例如創建String和Number作為Vector的基類型,實際上,Vector類的基類型可以是任何類。這也包括你定義的自定義類。例如,假設你的代碼定義了一個名為MyClass的類。在這種情況下,下面的代碼是有效的,它將創建一個Vector對象,它的元素都必須是MyClass實例:

var v:Vector.<MyClass> = new Vector.<MyClass>();

預設Vector的長度

Vector類構造函數有兩個可選參數,它允許你明確你的Vector實例的數量。第一個參數是length參數。默認情況下,當一個Vector被創建時,它是空的(它有0個元素)。然而,如果你傳遞一個值給length參數,明確元素數量的Vector實例就被創建了:

var myVector:Vector.<String> = new Vector.<String>(7); // myVector is created with 7 elements

預先確定Vector的大小比一次創建一個元素效率要高,所以,如果你提前知道Vector包含有多少元素,提供一個length參數值是比較好的。如果Vector的基類型是一個Boolean或者一個數值類型(Number,int,uint),每個元素都會被賦予這個數據類型的默認值(Boolean的默認值false,數據類型默認值0)。否則,每個元素初始值為null

創建一個可動態調整長度的Vector

Vector對象的另一個特征就是他們可以調整長度,這意味着你可以改變值,但是不能通過添加或刪除元素來改變總數。默認地,一個Vector實例是不允許動態修改長度的。要創建一個可修改長度的Vector,將Vector類構造函數的第二個參數(fixed參數)設置為true

var myVector:Vector.<String> = new Vector.<String>(7, true); // myVector's length is fixed to 7 elements

注意: 你可以在任何時候修改Vector對象的fixed屬性來設置Vector的長度是否可變。

myVector.fixed = false; // myVector's length is no longer fixed

為一個Vector對象添加值

除了一個額外的限制之外,添加一個值到Vector對象中與添加一個值到Array對象中類似。一個Vector對象的每個元素必須有一個值(或者null)。換句話說,你不能在一個序號為4的位置添加一個值,除非Vector的0–3為已經有值了。在實際中,這意味着要添加一個新的元素到Vector中,你必須在等於Vector對象長度的序號位置添加它(因為Vector的第一個元素序號為0,所以length屬性的值通常比Vector最后一個元素的序號要大)。下面的代碼演示了這一技巧:

var names:Vector.<String> = new Vector.<String>();
 
// ... assume some elements are added ...
 
// Add an element to the end of the Vector
names[names.length] = "Bob";

除了使用array訪問符([])操作添加一個值到Vector對象中外,你也可以使用Vector對象的push()或者unshift()方法來添加元素到Vector中。就像Array類一樣,push()方法創建了一個新元素在Vector最后一個元素的末尾,unshift()方法創建了一個新元素在Vector序號為0的位置(同時將所有已經存在的元素移位值高一位的位置):

names.push("Harold"); // adds the value "Harold" to the end of the Vector
names.unshift("Fred"); // adds the value "Fred" to the start of the Vector

這些方法還有額外的優勢是,你可以傳遞多個值做為參數給方法,所有的值都會一次性添加到Vector對象中。然后,這種彈性的方式也會導致一個后果。當你使用push()或者unshift()方法添加值到Vector對象時,編譯器不能檢查數據類型是否匹配。因為,任何使用push()或者unshift()添加錯誤類型的值到Vector對象中的代碼知道運行代碼時才會被發現。

從Vector對象中恢復值

從Vector對象中恢復值與從一個Array對象中恢復值完全一樣。要從特定序號位置回復元素值,你需要使用數組訪問符([])操作來明確你需要的元素序號:

var name1:String = names[0];

使用數組訪問符([])操作恢復值,但是不會將它從Vector對象中移除。要恢復值並且將它從Vector對象中移除,請使用pop()方法(它會移除最后的一個元素)或者shift()方法(它會移除第0個元素,並且所有元素減一位):

var finalName:String = names.pop(); // removes the last value from the Vector
var firstName:String = names.shift(); // removes the first value from the Vector

將一個Vector中的值進行排序

大部分使用Vector對象的方法與使用Array對象的方法都一樣。有一個方法你需要知道的不一樣的是在Vector對象元素排序。Vector類僅有一個方法給值排序:sort()方法。sort()方法不會更改原始的Vector對象。取而代之,它返回具有相同基類型包含已排序了值的一個新的Vector。

當你使用Vector類的sort()方法時,它沒有默認的排序行為,即使是基本的數據類型如Number或者String。正因為如此,任何時候你使用sort()方法,你都需要指明一個自定義的排序函數來定義排序邏輯。例如,下面的代碼中,一個Number類型的Vector對象使用sort()方法來排序。在這個案例中,這個代碼演示了基本的數據排序;小的數字放在大的數字前面(升序排列)。名為sortNumbers()的函數定義了排序行為,它做為一個參數傳遞給了sort()方法調用。Flash Player給每個數字排序時,它調用sortNumber()函數,將要進行比較的兩個數值傳遞給函數,結果決定最終排序的順序:

var numberVector:Vector.<Number> = new Vector.<Number>();
numberVector.push(2, 17, 3.6, 4.4, 29, -34, 0.09235);
 
trace(numberVector); // output: 2,17,3.6,4.4,29,-34,0.09235
 
var sortedVector:Vector.<Number> = numberVector.sort(sortNumbers);
 
trace(sortedVector); // output: -34,0.09235,2,3.6,4.4,17,29
 
function sortNumbers(x:Number, y:Number):Number
{
    if (x < y)
    {
        return -1;
    }
    else if (x > y)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

你可以定義為任意數據類型定義一個排序函數。例如,下面的代碼為Vector的Person對象根據姓氏(last name)進行了排序,然后是名字(first name)(它假定了有一個Person類具有firstNamelastName屬性):

var personVector:Vector.<Person> = new Vector.<Person>();
personVector[0] = new Person("Bob", "Smith");
personVector[1] = new Person("Harold", "Johnson");
personVector[2] = new Person("Barbara", "Smith");
personVector[3] = new Person("Arnold", "Anderson");
personVector[4] = new Person("Margaret", "Wooster");
 
// output:[Smith,Bob],[Johnson,Harold],[Smith,Barbara],[Anderson,Arnold],[Wooster,Margaret]
trace(personVector);
 
var sortedVector:Vector.<Person> = personVector.sort(sortPeople);
 
// output:[Anderson,Arnold],[Johnson,Harold],[Smith,Barbara],[Smith,Bob],[Wooster,Margaret]
trace(sortedVector);
 
function sortPeople(x:Person, y:Person):Number
{
    // sort by last name
    var lastNameSort:Number = sortStrings(x.lastName, y.lastName);
    if (lastNameSort != 0)
    {
        return lastNameSort;
    }
    else
    {
        // if the last names are identical, sort by first name
        return sortStrings(x.firstName, y.firstName);
    }
}
 
 
function sortStrings(x:String, y:String):Number
{
    if (x < y)
    {
        return -1;
    }
    else if (x > y)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM