Create a list of objects from a list of String in groovy - list

I am having a list of string as follows.
List l = ["1","2","3"]
And I have a class like as follows.
class person {
String name
}
I want to create a list of person object from List l.
I have tried using groovy list collect but I am not able to do so.
Here is my code.
class testJsonSlurper {
static void main(String[] args) {
List l = ["1","2","3"]
def l2 = l.collect { new person(it) }
println(l2)
}
}
But I getting following error.
Exception in thread "main" groovy.lang.GroovyRuntimeException: Could not find matching constructor for: testJsonSlurper$person(java.lang.String)

In your class testJsonSlurper, you have to change this line
def l2 = l.collect { new person(it) }
into
def l2 = l.collect { new person(name:it) }
This is what we call Named argument constructor. You can find more about Named argument constructor here.
If you do not want to make this change, then you need to add constructor in class person yourself.
The class person should look like this after adding constructor.
​class person {
String name
person(name){
this.name = name
}
}

Related

Dot notation for list of object in class

I have a "fixed list" in a class, I know all the objects that are in that list and I can refer to the objects through the names. The list is immutable, except for the parameters of every object contained in this list.
Something like this
class Object {
String name; // Know prior to build time
String color; // Can change
Object(this.name, this.color);
}
class MyClass {
List<Object> myList = [Object('apple', 'red'),
Object('banana', 'yellow'),
Object('mango', 'orange')];
}
I would like to access the members of the list like
final test = MyClass();
test.myList.apple.color = 'green'
Is there some "special list" that consent this type of access?
I tried using ENUM but they are not suitable for this problem.
A Map<String, String> would be better suited for what you are trying to do.
final colors = HashMap<String, String>();
colors['apple'] = 'green';

Unity3D - Integer List values don't get initialized in Constructor of Class

In my Unity3D Project I made a simple 2D Game and implemented a Data Manager to save and load Data. I created a List but get a NullReferenceException whenever I try to refer to it. I have a DataManager Class (saves & loads Data) and a UserData Class (stores the fields that are needed to be saved or loaded). In the User Data Class I declare in initialize a List of integer type. The List contains the unlocked Levels and it is initialized in the Constructor of the User Data Class.
This is the DataManager Class:
public static class DataManager
{
public static List<int> GetUnlockedLevels()
{
UserData userData = Load();
return userData.unlockedLevels; // This method returns nothing, not even null!
}
private static void Save(UserData data)
{
string path = GetDataFilePath();
BinaryFormatter binaryFormatter = new BinaryFormatter();
using (FileStream fileStream = File.Open(path, FileMode.OpenOrCreate))
{
binaryFormatter.Serialize(fileStream, data);
}
}
private static UserData Load()
{
string path = GetDataFilePath();
if (!File.Exists(path))
{
UserData userData = new UserData();
Save(userData);
}
BinaryFormatter binaryFormatter = new BinaryFormatter();
using (FileStream fileStream = File.Open(path, FileMode.Open))
{
return (UserData)binaryFormatter.Deserialize(fileStream);
}
}
And here comes the UserData Class:
[Serializable]
public class UserData
{
public int score;
public List<int> unlockedLevels;
public UserData()
{
score = 50;
unlockedLevels = new List<int>();
unlockedLevels.Add(1); //unlocked by default
unlockedLevels.Add(2); //unlocked by default
unlockedLevels.Add(3); //unlocked by default
}
}
The problem is: the first method of the DataManager "GetUnlockedLevels()" returns nothing.
The weird part: I have the exact same Data Manager in another project where it works properly. In that other project, the GetUnlockedLevels-method returns "System.Collections.Generic.List´1[System.Int32]" when I return it via "Debug.Log". But in the new project, the method returns literally nothing (not even null; the exception comes at a later point)
I am sure that I didn't make a copy-paste-mistake. What could be the root for this error?
What IDE are you using? I ask because the answer to your question is that you have a typo in your UserData constructor. Normally you would be alerted to this as soon as you built within your IDE as it would fail to compile.
[Serializable]
public class UserData
{
public int score;
public List<int> unlockedlevels; // This line
public UserData()
{
score = 50;
unlockedLevels = new List<int>(); // And this line
unlockedLevels.Add(1); // And this line
unlockedLevels.Add(2); // And this line
unlockedLevels.Add(3); // And this line
}
}
unlockedLevels
vs
unlockedlevels
Solution: the file was created but was empty. I manually deleted the saved file and from then it worked properly.

Want to check if object is in groovy list using .contains() or 'in'

import groovy.transform.EqualsAndHashCode;
#EqualsAndHashCode(includes="name")
class Activity {
public String name
public buildings = []
public rooms = [] as Set
Activity(name) {
this.name = name
}
}
thisActivity=new Activity("activity")
activityRegistry = []
// is false correct
activityRegistry.contains(thisActivity)
// add new item activity2
activityRegistry << new Activity("activity2")
// is true?????
activityRegistry.contains(thisActivity)
this code is pretty straight forward, I create an activityRegistry list, I compare empty list to object I created. naturally test fails. I create a new object on the fly using new that I insert into the list. I compare the list then to the first object created, which is not part of the list, and contains, or in passes. could someone shed some light on how? or why?
The AST "EqualsAndHashCode" only use 'properties' from the class. Properties, in groovy, are declared without a modifier ('public'), and getter/setter are automatically generated.
In your example, change public String name to String name.
See : What are 'properties' in Groovy?

Better way to write common function with parameter is different class

In my project, I have some functions like that:
func 1 (with 2 class: class1 and classs1_1):
List<class1> GetData1(class1_1 cls)
{
List<class1> list = new List<class1>();
cls = new cls();
//do something for cls, like cls.GetSpecialCase();
//fill data from cls to list, as using foreach to fill data to list
return list;
}
func 2 (with 2 class: class2 and classs2_2):
List<class2> GetData2(class2_2 cls)
{
List<class2> list = new List<class2>();
cls = new cls();
//do something for cls, like cls.GetSpecialCase();
//fill data from cls to list, as using foreach to fill data to list
return list;
}
How could I write a function like that (because I don't want to use a lot of functions as above):
common func (with T is class1, object cls is class1_1):
List<T> GetData(object cls)
{
List<T> list = new List<T>();
//how to recognize which class of cls
if(cls == class1_1) class1_1 other_cls = cls as class1_1;
if(cls == class2_2) class2_2 other_cls = cls as class2_2;
//do something for other_cls
//fill data from other_cls to list
return list;
}
I just want to pass parameter as object, and in the common function, I want to know which class I'm passing to so that I can treat to right class, and call right function.
Anyone helps me to solve this problem.
Thank you very much.
It sounds like you need:
An interface or abstract base class with the GetSpecialCase method
A generic method (with type parameters for both input and output) of
List<TResult> GetData<T, TResult>(T item) where T : ISpecialCase<TResult>
{
List<TResult> list = new List<TResult>();
var other = item.GetSpecialCase();
// Fill list via other
return list;
}
If you can't introduce an interface or base class, you could use dynamic typing, but I'd strongly recommend that you use polymorphism to express what the different classes have in common (GetSpecialCase here) if you possibly can.
you can use generics also for the input type.
your code could be something like:
List<T> GetData<T>(T cls)
{
List<T> list = new List<T>();
//no need to recognize which class of cls
//do something for other_cls
//fill data from other_cls to list
return list;
}
and both classes needs to implement the same interface so you wouldn't need to know which type it is...

Is it possible to overload a constructor that accepts a list in scala?

I am trying to overload the constructor to a class so that it can accept lists of two different types of objects:
class myClass(){
var someStrings: List[String]=List[String]()
println("hello!")
def this(strings : List[String])={
this()
this.someStrings=strings
}
def this(ints: List[Int])={
this()
this.someStrings=ints.map(x => x.toString)
}
}
In this case, accept a list of ints or strings, and save a list of strings to the variable someStrings. The code above doesn't work:
error: double definition:
constructor myClass: (strings: List[String])myClass at line 12 and
constructor myClass: (ints: List[Int])myClass at line 17
have same type after erasure: (strings: List)myClass
def this(ints: List[Int])={
^
Is there a better way of doing this in scala? (Other than taking List[Any] and testing the elements)
Thanks!
create functions on a companion object which do the construction for you in a typesafe way that can be checked at compile time:
class myClass(){
var someStrings: List[String]=List[String]()
println("hello!")
}
object myClass {
def fromStrings(strings: List[String]) = {
val c = new myClass
c.someStrings = strings
}
def fromInts(ints: List[Int]) = {
val c = new myClass
c.someStrings = ints.map(_.toString)
}
}
object Usage {
val c1 = myClass.fromStrings(List("a","b","c"))
val c2 = myClass.fromInts(List(1,2,3))
}
I would urge you to avoid overloading in general, or checking types at runtime, when you could be checking types at compile-time instead
That's what DummyImplicit is for:
def this(strings: List[String])={
this()
this.someStrings=strings
}
def this(ints: List[Int])(implicit d: DummyImplicit)={
this()
this.someStrings=ints.map(x => x.toString)
}
This makes the erased signatures of constructors (i.e. the ones JVM sees) MyClass(List) and MyClass(List, DummyImplicit), so the overloading is allowed.
However, as #stew says, it could be a better idea to avoid overloading in this case.
In addition to the other answer, another thing you can do is use Arrays. The type information on an array is kept at runtime, so you can do overloading based on the type parameter.
class myClass() {
var someStrings: Array[String] = Array[String]()
println("hello!")
def this(strings: Array[String]) = {
this()
this.someStrings = strings
}
def this(ints: Array[Int])={
this()
this.someStrings = ints.map(x => x.toString)
}
}
Arrays are much underused in my opinion