Uploaded image for project: 'Groovy'
  1. Groovy
  2. GROOVY-4946

Groovy getAt cannot be used with lazily initialized lists

    XMLWordPrintableJSON

Details

    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:

      Example.groovy
      @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.

      Attachments

        Activity

          People

            paulk Paul King
            overzealous Phil DeJarnett
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: