An object array is a fixed-size sequence of objects:
def a= newObject[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 nullassert a instanceofObject[]
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]= falseassert 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}'
The subscript used in constructing object arrays is evaluated as an integer:
assertnewObject[ 0x100000003 ].size() == 3
//index coerced to integer, positive or negative
try{ newObject[ 0x80000000 ]; assert 0 }
catch(e){ assert e instanceof NegativeArraySizeException }
We can specify the initial collection of contained objects when we construct the array. Those objects can be any other entity in Groovy, eg, numbers, boolean values, characters, strings, regexes, lists, maps, closures, expandos, classes, class instances, or even other object arrays:
def aq= [1,2]
assert ([ aq, 3 ] as Object[]).clone()[0].is( aq )
//clone() makes a shallow copy only
We have a special syntax for constructing multi-dimensional object arrays with null initial values:
assert [ newObject[3], newObject[2], newObject[1] ] as Object[]
//usual syntax
assert [ newObject[3], newObject[3], newObject[3] ] as Object[]
//usual syntax when each constituent array of equal size
def m= newObject[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
}
}
We must specify the size of at least the first, outermost, dimension of an object array when we first create it:
There are strict rules concerning evaluation when subscripting object arrays:
class MyException extends Exception{}
def exception(){ thrownew MyException() }
def i, a, b
i= 4
a= newObject[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= newObject[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= nulltry{ 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 }
Implementing an ArrayList with an Object Array
ArrayLists are implemented with object arrays internally. Each ArrayList instance has a capacity, the size of a fixed-size array used to store the elements. This array is always at least as large as the list size, and its capacity grows automatically as elements are added to the list. To see the internal capacity of lists constructed with various values:
For efficiency, we can increase the capacity of a list before adding a large number of elements:
class Extras{ static enq(List l){l.elementData.size()} }
use(Extras){
list= []
list.ensureCapacity(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
}
We can see how many times a list has been modified: