map constructor for List<CustomObject> ?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
plg
Reply | Threaded
Open this post in threaded view
|

map constructor for List<CustomObject> ?

plg
Hi all,

I'm doing a little YAML-parsing where I have CustomObjects having Lists
of other CustomObjects as properties, but the default map constructor
does not seem to work for these lists.
example:

class Sample {
   Integer age
   String name
}
class SampleCollection {
   String name
   List<Sample> listOfSamples
}
def m = [name:'Collection1',listOfSamples:[
[age:10,name:'Anna'],[age:12,name:'Berta'] ]]
def c = m as SampleCollection // or c = new SampleCollection(m)
assert c.class == SampleCollection // passes
assert c.listOfSamples[0].class == Sample // fails

First solution I've come up with is adding a custom constructor to
SampleCollection like this:

   SampleCollection(Map map) {
     name = map.name
//     listOfSamples = map.listOfSamples // cast not working
     listOfSamples = []
     map.listOfSamples.each{ sample ->
       listOfSamples << (sample as Sample)
     }
   }

This works, but seems rather inefficient, as
a) I have to loop through each list with potentially many items and
b) SampleCollection has some more simple properties like 'name', which I
don't want to add all manually. Is there a way to use the default for
these simple properties?


regards
Paul
--
typed with Neo 2 -- an ergonomically optimized keyboard layout
for German, English, programming, and science

http://neo-layout.org/
Reply | Threaded
Open this post in threaded view
|

Re: map constructor for List<CustomObject> ?

Anthony Hepple
Hi Paul

If you provide just a setter for listOfSamples, instead of a map constructor that handles all properties, then you can allow Groovy's dynamic map construction process to handle all the other properties. Something like this...

class Sample {
  Integer age
  String name
}
class SampleCollection {
  String name
  List<Sample> listOfSamples = []

  def setListOfSamples (List samples) {
    samples.each { sample ->
       listOfSamples << (sample as Sample)
    }
  }
}
def m = [name:'Collection1',listOfSamples:[ [age:10,name:'Anna'],[age:12,name:'Berta'] ]]
def c = m as SampleCollection // or c = new SampleCollection(m)
assert c.class == SampleCollection // passes
assert c.listOfSamples[0].class == Sample // NOW PASSES
assert c.listOfSamples[0].name.class == String
assert c.listOfSamples[0].age.class == Integer


On 10 November 2017 at 11:04, paul <[hidden email]> wrote:
Hi all,

I'm doing a little YAML-parsing where I have CustomObjects having Lists of other CustomObjects as properties, but the default map constructor does not seem to work for these lists.
example:

class Sample {
  Integer age
  String name
}
class SampleCollection {
  String name
  List<Sample> listOfSamples
}
def m = [name:'Collection1',listOfSamples:[ [age:10,name:'Anna'],[age:12,name:'Berta'] ]]
def c = m as SampleCollection // or c = new SampleCollection(m)
assert c.class == SampleCollection // passes
assert c.listOfSamples[0].class == Sample // fails

First solution I've come up with is adding a custom constructor to SampleCollection like this:

  SampleCollection(Map map) {
    name = map.name
//     listOfSamples = map.listOfSamples // cast not working
    listOfSamples = []
    map.listOfSamples.each{ sample ->
      listOfSamples << (sample as Sample)
    }
  }

This works, but seems rather inefficient, as
a) I have to loop through each list with potentially many items and
b) SampleCollection has some more simple properties like 'name', which I don't want to add all manually. Is there a way to use the default for these simple properties?


regards
Paul
--
typed with Neo 2 -- an ergonomically optimized keyboard layout
for German, English, programming, and science

http://neo-layout.org/



--
Anthony Hepple
01704 227828 / 07931 504049
http://www.dhdevelopment.co.uk
plg
Reply | Threaded
Open this post in threaded view
|

Re: map constructor for List<CustomObject> ?

plg
Am 11.11.2017 um 17:55 schrieb Anthony Hepple:
> If you provide just a setter for listOfSamples, instead of a map
> constructor that handles all properties, then you can allow Groovy's
> dynamic map construction process to handle all the other properties.
Thanks Anthony,

guess that was just too simple and obvious for me to notice :D

Nevertheless I'd be interested in WHY the list-entries are not cast
automagically. Does Groovy even check the <T> type of list elements, or
just ignores it?
If someone can give me some insights, that would be much appreciated.

thanks in advance,
Paul

> On 10 November 2017 at 11:04, paul <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     Hi all,
>
>     I'm doing a little YAML-parsing where I have CustomObjects having
>     Lists of other CustomObjects as properties, but the default map
>     constructor does not seem to work for these lists.
>     example:
>
>     class Sample {
>        Integer age
>        String name
>     }
>     class SampleCollection {
>        String name
>        List<Sample> listOfSamples
>     }
>     def m = [name:'Collection1',listOfSamples:[
>     [age:10,name:'Anna'],[age:12,name:'Berta'] ]]
>     def c = m as SampleCollection // or c = new SampleCollection(m)
>     assert c.class == SampleCollection // passes
>     assert c.listOfSamples[0].class == Sample // fails
>
>     First solution I've come up with is adding a custom constructor to
>     SampleCollection like this:
>
>        SampleCollection(Map map) {
>          name = map.name <http://map.name>
>     //     listOfSamples = map.listOfSamples // cast not working
>          listOfSamples = []
>          map.listOfSamples.each{ sample ->
>            listOfSamples << (sample as Sample)
>          }
>        }
>
>     This works, but seems rather inefficient, as
>     a) I have to loop through each list with potentially many items and
>     b) SampleCollection has some more simple properties like 'name',
>     which I don't want to add all manually. Is there a way to use the
>     default for these simple properties?

--
typed with Neo 2 -- an ergonomically optimized keyboard layout
for German, English, programming, and science

http://neo-layout.org/