• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Groovy script List / Map collection

 
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi All,

Firstly, I'm new to Groovy so apologies in advance for any school boy errors in the below.

I've created a script which I'm using to simulate the behaviour of a SOAP service in SOAP UI (as a mock service) for sprint testing purposes but am having problems when trying to iterate over a List I've created. The List is made up of a number of Maps, and each Map contains a List. It should look something like this:

[[Rec: 1, Items: ["AB123","BC234","CD345"],[Rec: 2, Items: ["AB123","BC234","CD345","DE456"]]

And this is the code I have to build up the List:

def offerMap      = [:]
def outputList    = []
def offerItemList = []

def outputMap     = [:]
def outList       = []

def item          = ""
def row           = ""

offerItemList.add("AB123")
offerItemList.add("BC234")
offerItemList.add("CD345")

offerMap.put("Rec",1)
offerMap.put("Items",offerItemList)

outputList.add(offerMap)

log.info "OUT: outputList.size ${outputList.size()}"
log.info "OUT: offerItemList.size ${offerItemList.size()}"

offerMap.clear()
offerItemList.clear()

offerItemList.add("AB123")
offerItemList.add("BC234")
offerItemList.add("CD345")
offerItemList.add("DE456")

offerMap.put("Rec",2)
offerMap.put("Items",offerItemList)

outputList.add(offerMap)

log.info "OUT: outputList.size ${outputList.size()}"
log.info "OUT: offerItemList.size ${offerItemList.size()}"

And this is the the code I have to iterate over the list:

outputList.each {

   log.info "OUT: outputList.size ${outputList.size()}"

   outputMap.clear()
   outputMap = it

   row = outputMap.get("Row")
   log.info "OUT: ROW ${row}"
 
   outList.clear()
   outList = outputMap.get("Items")
 
   outList.each {
 
       item = it
       log.info "OUT: Item ${item}"
 
   }
}

But this is not giving me the results I expect, first problem is that the .each loop for outputList appears to immediately be jumping to the second entry in the list, as witnessed from the output:

Fri Nov 03 17:54:32 GMT 2017:INFO:OUT: outputList.size 1
Fri Nov 03 17:54:32 GMT 2017:INFO:OUT: offerItemList.size 3
Fri Nov 03 17:54:32 GMT 2017:INFO:OUT: outputList.size 2
Fri Nov 03 17:54:32 GMT 2017:INFO:OUT: offerItemList.size 4
Fri Nov 03 17:54:32 GMT 2017:INFO:OUT: outputList.size 2
Fri Nov 03 17:54:32 GMT 2017:INFO:OUT: ROW 2
Fri Nov 03 17:54:32 GMT 2017:INFO:OUT: Item AB123
Fri Nov 03 17:54:32 GMT 2017:INFO:OUT: Item BC234
Fri Nov 03 17:54:32 GMT 2017:INFO:OUT: Item CD345
Fri Nov 03 17:54:32 GMT 2017:INFO:OUT: Item DE456
Fri Nov 03 17:54:32 GMT 2017:INFO:OUT: outputList.size 2
Fri Nov 03 17:54:32 GMT 2017:INFO:OUT: ROW null

I'm running out of ideas and fear I may be missing something fundamental due to my lack of experience with Groovy.

If you can put me right, I'd be most grateful.

TIA
 
Ranch Hand
Posts: 734
7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The clear() method of ArrayList and HashMap used throughout the script clear the memory block of the variable but the variable retains the memory address pointing to. In a sense, it is live.

Hence, for the establishment of offerItemList, even though it has the size of 2, both entries are the same and are what you add to it the last (ie, [Rec:2,...] one). This explains why outputList.each {} starts out with the map entry with Rec being 2 and the entry 1 nowhere seen.

And then within the .each loop, once you apply clear to outputMap and outList, the offerItemList itself becoming containing 2 entries, each being empty hash map, hence, this explains as you see that the outList.each {} actually not executed at all (see your output).

The easiest way to see that effect is to add some log just after each line calling the clear method.

The proper way to do what you intend to do is to instead of calling clear, reuse/redefine the variable by using its constructor again. Then, a new memory address is re-allocated to it and the old memory block being still referenced to by the list or map's entry and will not be at risk of being garbage collected.

Those lines are these;

With those corrections, it should run fine.
 
reply
    Bookmark Topic Watch Topic
  • New Topic