...
| Code Block |
|---|
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}' |
...
| Code Block |
|---|
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 } |
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:
| Code Block |
|---|
assert [ 14.25, 17g, [1,2,3], 'Hello, world', ['a', false, null, 5] as Object[], new Object[200], { it*it }, ArrayList, ] as Object[] |
We can make a shallow copy using clone():
| Code Block |
|---|
def aq= [1,2]
assert ([ aq, 3 ] as Object[]).clone()[0].is( aq )
//clone() makes a shallow copy only
|
...
| Code Block |
|---|
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 } } |
We must specify the size of at least the first, outermost, dimension of an object array when we first create it:
| Code Block |
|---|
//ar= new Object[] //compile error when uncommented
ar= new Object[10][]
ar= new Object[10][][]
ar= new Object[10][10][]
|
A multidimensional array need not have arrays of the same length at each level. Thus, a triangular matrix may be created by:
| Code Block |
|---|
def triangle= new Object[100][]
(0..<triangle.length).each{
triangle[it] = new Object[it+1]
}
|
There are strict rules concerning evaluation when subscripting object arrays:
| Code Block |
|---|
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 of a subscript throws exception, subscripts to the right aren'tnot 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 }
|
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:
| Code Block |
|---|
class Extras{
static enq(List l){ l.elementData.size() }
}
def measure= { list, times->
def sizes= []
times.times{
def size
use(Extras){ size= list.enq() }
(size - list.size() + 1).times{ list << 'a' }
sizes << size
}
sizes
}
def list1= new ArrayList()
def measure1= measure(list1, 10)
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
|
...
| Code Block |
|---|
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:
...