來源自 這裡
Preface:
一個 Object 陣列為一個固定長度的 Object 序列:
在建立陣列過程中, 在 '[' 與 ']' 中的字符會被轉為
Integer 類型:
當你使用 '[' 與 ']' 建立陣列時, 在 Groovy 是使用
ArrayList 來承接裡面給的東西. 但如果真的需要的是陣列, 可以透過 as 關鍵字轉型:
當使用
clone() 進行物件複製時, 進行的是 shallow copy:
底下是多維度的 Object 陣列宣告範例, 初始值為 null:
底下是在進行陣列索引時的規則範例:
Implementing an ArrayList with an Object Array:
ArrayList 是使用陣列實作的 Array, 而初始的陣列大小為 10. 當你不斷的往裡面添加元素時, 當原先的陣列不夠使用時則會擴充成更大的陣列 (size=10->size=16), 底下的範例代碼檢視這個行為:
因為每次的陣列擴充的是時間的 cost, 因此當你已經知道要加入大量的元素前, 你可以先加大陣列的大小, 以避免不斷的陣列擴充造成的時間成本:
Groovy 的 array 在變更次數 (
添加/刪除 元素) 可以透過下面範例觀察:
Supplement:
* Stackoverflow > How do I use groovy's AS keyword
* Stackoverflow > Groovy type conversion
Preface:
一個 Object 陣列為一個固定長度的 Object 序列:
- def a= new Object[4] //we must specify the size of the fixed-size array
- assert a.size() == 4
- assert a.length == 4 //field alternative to size()
- a.each{ assert it == null } //default value is null
- assert a instanceof Object[]
- assert a.class == Object[]
- a[0]= 'a'
- a[1]= 2 //elements can be any value
- a.putAt(2, 'c') //alternative method name syntax
- a[3]= false
- assert a[0] == 'a' && a[1] == 2 && a.getAt(2) == 'c' && a.getAt(3) == false
- //either subscript or method name
- assert a[-4] == 'a' && a[-3] == 2 && a[-2] == 'c' && a[-1] == false
- //subscripts can be negative
- try{ a[4]; assert 0 }
- catch(e){ assert e instanceof ArrayIndexOutOfBoundsException }
- try{ a[-5]; assert 0 }
- catch(e){ assert e instanceof ArrayIndexOutOfBoundsException }
- assert a[1..2] == [2, 'c'] //we can use the same subscripting as for lists
- assert a[2..2] == ['c']
- assert a[0, 2..3] == ['a', 'c', false]
- assert a.toList() == ['a', 2, 'c', false]
- assert a as List == ['a', 2, 'c', false]
- assert a.toArrayString() == '[a, 2, c, false]'
- assert new Object[ 0x100000003 ].size() == 3
- //index coerced to integer, positive or negative
- try{ new Object[ 0x80000000 ]; assert 0 }
- catch(e){ assert e instanceof NegativeArraySizeException }
- def m = [1,'2',false]
- assert m.class.getName() == "java.util.ArrayList"
- m = [1,'2',false] as Object[] // 轉成 Object 陣列!
- assert m.class.name == "[Ljava.lang.Object;"
- class X{
- def name
- }
- def x = new X(name:"John")
- def aq= [1,2,x]
- def bq = ([ aq, 3 ] as Object[]).clone()
- assert bq[0].is( aq ) // 使用 is 來判斷是否指向同一個物件.
- x.name = "Peter"
- assert bq[0][2].name == "Peter" // 因為是 shallow copy, 所以變更 x 會影響到 clone 後的物件
- assert [ new Object[3], new Object[2], new Object[1] ] as Object[]
- //usual syntax
- assert [ new Object[3], new Object[3], new Object[3] ] as Object[]
- //usual syntax when each constituent array of equal size
- def m= new Object[3][3]
- //special syntax when each constituent array of equal size
- (0..<m.size()).each{i->
- (0..<m[i].size()).each{j->
- assert m[i][j] == null
- //we can also subscript with special syntax using consecutive indexes
- }
- }
- class MyException extends Exception{}
- def exception(){ throw new MyException() }
- def i, a, b
- i= 4
- a= new Object[i][i=3] //first subscript evaluated before next one
- assert a.size() == 4 && a[0].size() == 3
- a= [ 11, 12, 13, 14 ] as Object[]
- b= [ 3, 2, 1, 0 ] as Object[]
- assert a[(a=b)[2]] == 12
- //outside of subscript evaluated before inside, ie, a[b[2]] or a[1] or 12
- i= 1 //if what's outside subscript throws exception, subscript isn't evaluated
- try{ exception()[i=2] }catch(e){ assert i == 1 }
- i= 1
- a= new Object[2][2]
- //if subscript evaluation throws exception, subscripts to right not evaluated
- try{ a[ exception() ][i=2] }catch(e){ assert i == 1 }
- //index evaluated before indexing occurs (including checking whether
- //what's outside subscript is null)...
- a= null
- try{ a[exception()]; assert 0 }catch(e){ assert e instanceof MyException }
- //NullPointerException never occurs here
- i= 1
- try{ a[i=2]; assert 0 }
- catch(e){ assert i == 2 && e instanceof NullPointerException }
ArrayList 是使用陣列實作的 Array, 而初始的陣列大小為 10. 當你不斷的往裡面添加元素時, 當原先的陣列不夠使用時則會擴充成更大的陣列 (size=10->size=16), 底下的範例代碼檢視這個行為:
- class Extras{
- static enq(List l){ l.elementData.size() }
- }
- def measure= { list, times->
- def sizes= []
- times.times{
- def size
- use(Extras){ size= list.enq() }
- printf "Size=$size;list.size()=%d\n", list.size()
- (size - list.size() + 1).times{ list << 'a' } // 故意加入 'a' 使原先的 list 剩餘空間不夠而必須進行 expand
- sizes << size
- }
- sizes
- }
- def list1= new ArrayList()
- def measure1= measure(list1, 10) // 對 list1 進行 10 次檢視每次 expand 的狀況 .
- assert measure1 == [10, 16, 25, 38, 58, 88, 133, 200, 301, 452]
- def list2= new ArrayList(10)
- def measure2= measure(list2, 10)
- assert measure2 == measure1
- def list3= new ArrayList(5)
- def measure3= measure(list3, 10)
- assert measure3 == [5, 8, 13, 20, 31, 47, 71, 107, 161, 242]
- def list4= []
- def measure4= measure(list4, 10)
- assert measure4 == [0, 1, 2, 4, 7, 11, 17, 26, 40, 61]
- def list5= new ArrayList(0)
- def measure5= measure(list5, 10)
- assert measure5 == measure4
- class Extras{ static enq(List l){l.elementData.size()} }
- use(Extras){
- list= []
- list.ensureCapacity(200) // 初始陣列大小為 200
- assert list.enq() == 200
- list<< 'a'<< 'b'<< 'c'
- assert list.enq() == 200
- list.trimToSize()
- //we can also trim the internal fixed-size array to the list size
- assert list.enq() == 3
- }
- list= []<< 'a' << 'b'; assert list.modCount == 2
- list.remove('a'); assert list.modCount == 3
* Stackoverflow > How do I use groovy's AS keyword
* Stackoverflow > Groovy type conversion
This message was edited 16 times. Last update was at 06/02/2014 12:38:05
沒有留言:
張貼留言