Reputation: 10975
I'm trying to create a lot of objects, but using new ObjectName(...)
over and over is not what I'm looking for.
new Obj("String", 0, true);
new Obj("Diff", 9, true);
new Obj("Changed", 2, false);
...
I would like something similar to:
massCreateObj({
{"String", 0, true },
{"Diff", 9, true },
{"Changed", 2, false}
...
});
I want to do this because it will be easier to manage for multiple objects, such as:
massCreateObjs({
"Obj" => {
{"str", 0, false},
{"sss", 1, true}
},
"Obj2" => {
{false, "different"},
{true, "diff"}
}
});
Otherwise, I would have to flatten this:
new Obj("str", 0, false);
new Obj("sss", 1, true);
new Obj2(false, "different");
new Obj2(true, "diff");
This is just simply not scalable. With an array, I can easily see which objects are being created, and there isn't text repeated (the new object name).
Is there a way I can use Hashmaps, Arrays, or tuples to accomplish this? (Open to other solutions too)
I've taken a look at hashmaps but it's essentially only a K->V setup.
I've also looked at wrappers, but then, it's back to where I've started. If I create a class/interface, I still need to use new class name or whatever, which is what I'm avoiding in the first place.
Upvotes: 0
Views: 65
Reputation: 10975
Here's my solution. I know this isn't codereview, but is this OK?
import java.lang.reflect.Constructor;
import java.util.Array;
public class MassCreate {
private Array<Obj> objs = new Array<Obj>();
public MassCreate(Object[][][] components) {
Constructor<?> construct = null;
try {
for (int i = 0; i < components.length; i++)
for (int i2 = 0; i2 < components[i].length; i2++)
if (i2 == 0) {
Class<?>[] classes = new Class[components[i][i2].length - 1];
for (int i3 = 1; i3 < components[i][i2].length; i3++)
classes[i3 - 1] = (Class<?>) components[i][i2][i3];
construct = ((Class<?>) components[i][i2][0])
.getConstructor(classes);
} else
objs.add((Obj) construct
.newInstance(components[i][i2]));
} catch (Exception e) {}
}
public Obj[] getObjs() {
Obj[] export = new Obj[objs.size];
for (int i = 0; i < objs.size; i++)
export[i] = objs.get(i);
return export;
}
}
Now for the fun part, here is where I can spawn new objects using an Object[][][]
.
Object[][][] components = {
{
{Obj.class, String.class, int.class, boolean.class},
{"test 1", 0, true},
{"test 2", 3, false}
},
{
{Obj2.class, boolean.class, String.class},
{true, "hello"},
{false, "diff"}
}
};
new MassCreate(components).getObjs(); //Obj2 extends Obj
Here's what it means:
{Obj.class, String.class, int.class, boolean.class}
The first class indicates what to make, and the rest indicate which constructor to use. So for this, the constructor for Obj.class would be:
public Obj(String str, int num, boolean bool);
The following items in the first level array are objects to be, so:
{"test 1", 0, true},
{"test 2", 3, false}
Would invoke the above constructor twice with these values.
What do you guys think?
Upvotes: 0
Reputation: 26185
Rather than specifying the objects in Java, read their parameters from a file. that file can be in any format you like, and can parse. Write Java code to call from the constructor for the object containing the array that reads the file and generates the array from it.
As a variation on this, write a separate program that reads and parses the file, and generates a Java program from it. That way, you could literally copy over initializers like Color.BLUE
.
Upvotes: 1
Reputation: 77187
If you want to create the array inline, you can always do
Obj[] objects = new Obj[] {
new Obj("String", 0, true),
new Obj("Diff", 9, true),
new Obj("Changed", 2, false)
};
There's no way to get around using new
(or some wrapper factory function that calls it) if you're trying to create a new object.
On a broader scale, by the way, your use case sounds like what you really want is immutable data structure, and you should consider Guava's ImmutableList
instead of a bare array.
Upvotes: 0
Reputation: 11
Make an inner class called "Node" if the input data follow specific types e.g. str, int, boolean, str, int, bool and create each Node object and put it in HashMap if object has names or in HashTable incase no names.
Upvotes: 0
Reputation: 4464
You can use Reflections, but you'd have to define your own function as follows:
public static <T> Object[] multipleConstructor(Class<T> type,
Object[]... initargs) {
ArrayList<T> list = new ArrayList<>();
@SuppressWarnings("unchecked")
Constructor<T>[] ctors = (Constructor<T>[]) type.getConstructors();
for (int i = 0; i < initargs.length; i++) {
for (Constructor<T> c : ctors) {
try {
list.add(c.newInstance(initargs[i]));
break;
} catch (Throwable t) {
continue;
}
}
}
return list.toArray();
}
Upvotes: 1
Reputation: 459
If you want to hard code the parameters in your code but want to avoid repeating the "new" keyword, then a simple loop will do.
String[] args1 = {"hello", "bye", "potatoe"};
int[] args2 = {5,2,7};
boolean[] args3 = {true,false,true};
Obj[] objects = new Obj[3];
for (int i = 0; i < 3; i++) {
objects[i] = new Obj(args1[i], args2[i], args3[i]);
}
Not that this is good code, but the idea can be applied in better ways :)
Upvotes: 1