We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Does anyone know why, with an IntList that has less than 10 elements, using list.get(n) for values of n greater than the last index and less than 10 returns 0 as opposed to giving an "index out of bounds" error?
Answers
IntList and many of such are new-comers in Processing 2+! =D>
In particular, IntList was meant to replace Java's ArrayList<Integer>.
But w/ the added bonus of storing faster primitive
int
values rather than references for Integer wrappers! \m/Both of them have an underlying array instance to store its entries though. And as most of us know, arrays can't be resized!
If we need to, we gotta create another 1 w/ the length we wish and transfer everything to that and discard the old 1!
From that we can conclude that the # of items stored, its size(), are
<=
to the current capacity, the length, of the internal array.Whilst an ArrayList always checks whether we try to use an index
>=
of its size(), the new storage classes are much less strict!I find it cool, b/c besides not being that important, it's 1 less bottleneck performance-wise!
And that's stacked upon the fact that they already store primitive values instead! =:)
An IntList starts out w/ capacity 10. That's why we can access up to index 9, even though its size() is less than that!
Likewise a List, we can specify its initial capacity when we instantiate it.
But unlikewise, we can initiate it w/ an array too! :ar!
"I find it cool"
I find it inconsistent, because a.get(8) is 0 and a.get(88) throws an error in an uninitialized IntList...
As I had already informed, initial capacity is 10. Thus indices from 0 to 9 are already available from the get-go!
But size() method is still firmly consistent to the highest index set. It's not that bad! ~:>
Nonetheless, if you do insist, you can instantiate it w/ initial capacity set to 0 ->
new IntList(0);
.Or if it's about known how many we're gonna need, it's even better to use that as initial capacity:
Anyways, just keep playing safe as we already do w/ more strict bound-check data-structures.
That is, in doubt, always check size() before accessing an item from it, rather than shoot in the dark! [..]
Thanks for the explanation. When I try to set the capacity to 0 and then append an element, I get an "ArrayIndexOutOfBoundsException: 0". If I set the capacity to 1, I don't get the error, but then if I add more items to the list, the list grows by doubling. So there will always be cases where it won't throw index out of bounds exceptions the way an ArrayList would, but the size() function is consistent. OK. And if checking the size during every call to an IntList function would slow things down, and speed more than convenience is the priority, then OK. Thanks again.
That doubling behavior is the same for ArrayList and List in general too! (~~)
That is, if we try to append()/add() or set() w/ an index >= its capacity, capacity is doubled! :(|)
I've been looking at IntList's source code:
https://github.com/processing/processing/blob/master/core/src/processing/data/IntList.java
And below the reason why get() is so "anarchist" but fast:
And I've found a fix for your "problem" -> a secret method called values() which invokes top secret private method crop(): >:)
And their respective source codes: (*)
Also, a way to initialize an IntList w/ a numerical sequence: :bz
"That doubling behavior is the same for ArrayList and List in general too!"
From memory, it uses to be the case, but now Java uses a more conservative growing scheme, using a factor around 1.3, IIRC.
"if checking the size during every call to an IntList function would slow things down"
You should not worry about this "slow down", it would count in microseconds (at worst) per draw() loop (16,666 µs by default!).
IntList and FloatList have an inconsistent bound management · Issue #2341