ArrayListは自動的にサイズが大きくなる配列です。
C++のSTLを知っている人は分かると思いますが、
たぶんvectorに似ています。
JScriptの
Arrayよりも便利な面もあり、
速度も格段に速いのでこれを使いましょう。
自動的に配列が大きくなるとは、
次のように要素を追加していくにつれてサイズが大きくなることです。
arraylist_add.js
--------------------------------------
import System;
import System.Collections;
var ary : ArrayList = new ArrayList();
//要素を追加
ary.Add("POSKA");
ary.Add("マスカラ");
ary.Add("100円玉");
//要素を全て表示
for(var i = 0; i < ary.Count; i++) //i=0,1,2
print(i + " : " + ary[i]);
Addメソッドで要素を追加していきます。
配列の大きさは
Countで得ます。
要素へのアクセスは普通の配列と同様です。
ArrayListには配列の大きさを表すCountとは別に格納できる要素の数を表す
Capacityというプロパティがあります。
arraylist_capacity.js
--------------------------------------
import System;
import System.Collections;
var ary : ArrayList = new ArrayList();
print(ary.Capacity); //16
ary.Add("POSKA");
ary.Add("マスカラ");
ary.Add("100円玉");
print(ary.Capacity); //16
最初から16個分は確保されているようです。
さらにAddを繰り返していくと、その容量を超えた場合、容量は倍になります。
Capacityが変わるということは、
恐らく新たに領域を確保して要素をそこにコピーしなければならないと思われます
(ホントはどうなのか知りませんが)。
最初から十分な領域を確保しておけばその動作がいらなくなり、
実行速度が上がると推測されます。
次のプログラムは漸化式、
a0 = a1 = 1
ai+2 = ai+1 + 1/ai (i >= 0)
で a
200001 を求めます(本当は配列を使う必要はないのですが)。
arraylist_add2.js
------------------------------------------
import System;
import System.Collections;
var t : int = Environment.TickCount;
var n : int = 200000;
var a : ArrayList = new ArrayList();
a.Add(1);
a.Add(1);
for(var i : int = 0; i < n; i++)
a.Add(a[i+1] + 1 / a[i]);
print(a[n+1]);
print((Environment.TickCount - t) + "ms");
これに対して、最初に十分な領域を確保しておくのが次のコードです。
arraylist_add3.js
------------------------------------
...
var a : ArrayList = new ArrayList();
a.Capacity = n + 2; //領域確保
...
Capacityプロパティを大きくすることによって、
最初に領域を確保しています。
最初のは480msかかっていますが、このコードだと230msで済みました。
ちなみにJScriptのArrayオブジェクトを使った場合は、
arraylist_add5.js
--------------------------------
...
var a = [ 1, 1 ];
for(var i : int = 0; i < n; i++)
a[i+2] = a[i+1] + 1 / a[i];
...
コードはいくぶん分かりやすくなりますが、1800msかかっています。
ArrayListの代入はArrayオブジェクトと同じようにアドレスを渡すことになります。
...
var a : ArrayList = new ArrayList();
for(var i = 0; i < 10; i++)
a.Add(i);
var b = a; //アドレスを渡している
print(b[9]); //9
a[9] = 0;
print(b[9]); //0
Arrayオブジェクトでは要素をすべてコピーするのは面倒でしたが、
ArrayListには
Cloneというメソッドが用意されています。
...
var b = a.Clone(); //簡易コピー
a[9] = 0;
print(b[9]); //9
ただし、コピーするのは要素だけで、
その要素が参照型の場合、アドレスがコピーされることになります。
...
var a : ArrayList = new ArrayList();
a.Add([1, 2]); //Arrayオブジェクトが要素
var b = a.Clone(); //簡易コピー
print(b[0][1]); //2
a[0][1] = 0;
print(b[0][1]); //0