Details
-
Bug
-
Status: Closed
-
Minor
-
Resolution: Fixed
-
1.8.1
Description
I'm not sure if this should even be logged as a bug, but here goes:
I was playing around with the Apache Commons ListUtils.lazyList. This list will automatically create an item if an index is not yet defined (or is null). Example code:
@Grab(group='commons-collections', module='commons-collections', version='[1.3,)') import org.apache.commons.collections.ListUtils import org.apache.commons.collections.Factory import groovy.transform.Canonical @Canonical class Test { String name int amount } List<Test> t = ListUtils.lazyList([], { new Test() } as Factory) // UNCOMMENT to make the example work: // t.get(1) // Thows NPE here: t[1].name = 'Jim' t[0].amount = 6 assert t == [new Test(null, 6), new Test('Jim', 0)]
However, I thought it was broken, because I had been running with without the commented t.get(1) line. The getAt code checks the size of the dynamic list, and since it is smaller, returns null. This causes an NPE to be thrown.
I realize that the lazy list breaks the List contract (by dynamically changing the list size). However, it seems like a fairly useful feature to have a lazily created list.
I'm not sure there is an acceptable solution, but returning null hides the problem in a way that is hard to debug! Maybe it would be better to have a withDefault method for lists, too, that works like the one for {{Map}}s. That would provide a usable solution without breaking the current design. Plus, you no longer have to include the commons library for that use case.