Wednesday, December 5, 2012

Specifing arrays size/capacity - my latest buggy code and a bestpractice

 
We're often required to specify size/capacity when allocating array like structures.

While you MUST specify size for Java's primitive arrays. With realizable arrays like ArrayList/Vector, specifying #capacity is too often a #premature-optimization, that you could avoid.




happened to introduce a bug to our code base, by initialized an ArrayList with a negative capacity value:

List<RetrievedDocument> docs =  new ArrayList<RetrievedDocument>(scoreDocs.length - resultsOffset);

Performing such profanity results in an #IAE being thrown (triggered by a NegativeArraySizeException thrown by the underlying primitive array structure.
public ArrayList(int capacity) {
firstIndex = lastIndex = 0;
try {
array = newElementArray(capacity);
} catch (NegativeArraySizeException e) {
throw new IllegalArgumentException();
}
}

Lesson for the next 50 years (or until I switch off from Java):

Whenever setting the size of an array (or anything sizable) to an unknown ahead value, spend a second to consider whether the value could be negative.
Then, if the desired resulting behavior is to create a zero-sized array instead, use this one-liner for that:
new ArrayList( Math.max(0, possiblyNegativeCapacity) );
Q: Do you know if other languages makes the use case above easier/less error prone?

Q: Any other related best practices and pitfalls you would like to share?