I want to create a java class with dynamic number of variables. Those dynamic variables will be read from a config file.
Example: I have a properties file like,
{
"data": "int",
"name": "string",
"addr": "string",
"age" : "int"
}
In some cases, new variables can be there or few variables are missing from above config.
I want to create a java with variables mentioned in above properties file. Is it possible in java to create such class and if yes then can someone provide sample code for that?
Define a Map<String, String> that you can access by the key,
but why?
at the end all those "variables" will be the same type... -> String...
the same principe is done in config or property files....
I think you need to do a bit more research on java classes. There is no java class that has a dynamic "number" of variables. But you can give a class attributes, but require only some are set, for example.
class DataFile {
int data;
String name;
String addr;
int age;
}
And then you can create setters and getters for each field.
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
That way you can instantiate a member of the class and set the data you have.
DataFile d = new DataFile();
d.setName("John");
Remember that any class methods like setName and getName have to be inside the { } that define the class to which they belong. They aren't here just to separate them visually.
All of that already exists. It is called "Properties" in Java, too.
So, simply read about them here!
In other words: you could/should use java.util.Properties; and there is full support for reading that information from files; or writing to.
The Java property file format does not match your current file format; but well, when you are doing "true" Java, then the most "off the shelf" solution are Java properties; so so you could consider to change your file format.
And to give the actual answer: Java does not support a dynamic number of fields. That is what Maps are used for; and the Property class is exactly that - some sort of Map with additional functionality.
How about something like this
public class Model {
Map model;
public Model(String json) {
model = new Gson().fromJson(jsonModel, Map.class);
}
public Object getValue(String key) {
return model.get(key);
}
}
But you'd rather want your model to hold data for values, leaving the type inference of the fields to Java.
Related
I am trying to create a helper method that will take in the names (type String) of the member variables (could be any number of member variables) and automatically initialize/create the member variables as well as the getter methods. So I would call something like:
helperClass("hello", "myName", "is", "bob")
and the helperClass would look something like this:
public class helperClass {
helperClass(String ...a) {
for (String s: a)
//create member variables and getter methods dynamically
}
So, in the end, the caller of the function would have something like this:
public class helperClass {
private String hello
private String myName
private String is
private String bob
//getter methods below
...
}
Coming from Python so wasn't sure if this type of stuff is doable in Java.
Yes. You can create the getter and setter methods dynamically.
Tutorial for Java Dynamic POJO creation . But this method will involve you creating a predefined string which contains the method declaration.
Eg :
String s= "public void doSonething(String ... args){ // Function Body }" .
You can then convert this string into a function at runtime. Based on your need, you can define a custom string that contains the method declaration which you need. See some examples in the above tutorial link I have attached.
i think the answer is to use an IDE. They all have "add property" functions which will generate the declaration and appropriately named getters and setters.
Should you prefer to manually enter your properties, They all also have generate getter/setter functions which will look at the properties you have entered (work out which getters and setters are missing) and offer to create approporiately named getters and setters in bulk for the ones you've selected.
To answer your specific question, yes you can write your own class that takes a list of strings (i.e. property names) and print them out as a series of getters and setters, this is basic string concatenation:
private String generateGetter(String propName) {
return String.format(" public String get%s()\n return this.%s;\n }", StringUtils.capitalize(propName), propName);
}
To convert the first letter of the propName to upper case (the convention for getter and setter methods, you can do it yourself or use apache's string utils.
so I have been trying to understand what property exactly mean. I have searched for previously asked Q/A in stackoverflow and other website but the answers that I came across were not specific as to whether fields(instance variables) that are modified with setters and getters are also called properties.
The definition I came across was "a combination of setters and getters methods that modify fields of an object"
Below is just a small piece of code to make you understand my question better if you need more clarification.
//property?
String name;
//property?
public void setName(String n){
name = n;
}
//property?
public String getName(){
return name;
}
Properties means any members that belongs to the class. It could be variable, objects of other/ same class, methods of that class etc.
basically getter/setter are used for those member variables only.
Local variables are properties of that method that it belongs to and not property of the class.
In the OOP world, "property" has a rather broad sense and its specific meaning depends on the context. Generally, it is an attribute of an entity; ith may be a name or an age of a person, a color of a flower, a height of a building etc. A property has its name and its value (e.g. flower.color = red -- here color is the name, and red is the value), the value may belong to different types (or classes): a string, a number, a person, an enterprise... It may have a constant value (that never change during the lifetime of the owner (the entity it belongs to)) or it may have a variable value that can be changed by the user. In the software area it can be talked about at a conceptual level of the domain analysis and the software design; in this case people usually don't care how exactly it would be implemented. As well, it may be used at the level of concrete implementation (program code), and then the means to implement this concept depend on the programming language.
In Java, for example, when we say 'property' we usually mean a field (variable) of an object and a couple of methods (or a single method for read-only properties) to access its value (getter and setter):
class Person {
private String name; // the field to hold the value
public Person(String name) { // Constructor
this.name = name // The name is given at the moment it's been born
}
public String getName() { return Name; } // getter
// No, name can't be changed after it's been born -- it's a read-only property, thus no setter
// public void setName(String name) { this.name = name; } // otherwise the setter would look like this
}
In such a case, a user can acces the value of the property with the following code:
System.out.println(thisPerson.getName());
Other languages (like C#, for example) have means to code properties in somewhat more convenient way:
class AnotherPersonType {
private string name // a field to hold the value
public string Name
{
get => name; // getter, the same as "return this.name;"
set => name = value; // setter, the same as "this.name = value;"
}
}
.....
anotherPerson.name = "John"; // It looks like an assignment,
// but in fact, the setter is invoked
Let's say I have a JSON file example.json
example.json
{
"BaggageMaxSize" : {
"mesurement" : "sum",
"width" : 70,
"height" : 50,
"depth" : 40
}
}
And create the POJO class:
public class pojoexample{
private BaggageMaxSize BaggageMaxSize;
// getter
// setter
}
And then:
public class BaggageMaxSize
{
private String height;
private String width;
private String depth;
private String mesurement;
// getter
// setter
}
Now, I want to use the mapper.readValue to change file to BaggageInfoPolicy.class:
BaggageInfoPolicy bip = mapper.readValue(file, BaggageInfoPolicy.class);
But bip.getBaggageMaxSize().getMesurement() returns null value. Any suggestions?
Try using mapper.writeValue first and check how your resulting JSON object will look like. Very likely, there's an issue with int -> string conversion in your BaggageMaxSize when deserialized from JSON.
Also, check your getters/setters to be publicly visible and be available both on pojoexample and BaggageMaxSize.
Actually your JSON represents a pojoexample class instance and not a BaggageInfoPolicy object, which you haven't shared in your post.
So you need to change your code to:
PojoExample bip = mapper.readValue(file, PojoExample.class);
So it reads the PojoExample object correctly.
Note:
Your class should follow the java naming convention and
start with an uppercase, that's why I changed it to PojoExample,
change it in the class definition as well.
And Make sure your class fields have the same types as in the JSON, and their getters and setters are correctly implemented.
I am relatively new to Java. I have been struggling to define a class that meets my needs. Searching on this site or google did not have probably because the question is so specific. Any help is appreciated!
Ideally the class (lets call it Filer) would have:
Name (string)
Volumes (Collection/list of Strings: 0 -100)
Each Volume, in turn, will have:
A. Name (string)
B. Servers_Permed (another collection/list of Strings: 0-40)
Once I can get the class defined, I will do ok with defining getters and setters to use it, but so far I have failed to defined the class without getting totally lost :-)
Thanks!
It seams that your description is not correct.
You need a class Filer with:
name (String)
volumes (list of Volume) (not strings as you asked, because you explained differently on the second part of the question, it is evident that you need a list of Volume and not a list of String)
And a second class Volume with:
Name (string)
Servers_Permed (list of strings)
So you need a data structure like the following:
public class Volume {
private String name;
private List<String> serversPermed; // Changed the name to a name more adherent to standard guidelines
...
}
public class Filer {
private String name;
private List<Volume> volumes;
...
}
well, lay it out piece by piece.
First, you have Volume (not sure how volumes could be "Collection/list of Strings: 0 -100" and have the following properties):
public class Volume {
String name;
List<String> servers_permed;
}
Now you have Filer:
public class Filer {
String name;
List<Volume> volumes;
}
you will have to add the necessary constructors, getters/setters.
Both of the answer given above worked beautifully (they are almost the same anyway).
Thank you, Davide and DBug!
There is a question on my mind for a while. Let's say we have the following classes:
public Class Person{
String name;
String address;
String description;
}
public Class PersonFacade{
String name;
String address;
String desc;
}
as you can see the only difference between these two classes are the name of one variable. My question is what is the best way to write a helper class to map the values of one object to another object. Let's assume we have the following:
Person person = new Person();
person.name="name1";
person.address="address1";
person.description="description1";
I want to write a class that is supposed to do the following (let's call it Transformer class)
PersonFacade personFacade = new PersonFacade();
TransformClass.transformFrom(person, personFacade);
What I want this TransformClass.transformFrom() method to do is the follwoing:
based on the similarity of the variable names, assign the value of the variable from "FromClass" to "ToClass"
so in our case, I want it to assign personFacade.name = "name1", personFacade.address="adderss1" and personFacade.desc = "description1" (this last one seems harder to accomplish, but let's try)
Any ideas?
You can use Dozer:
Dozer is a Java Bean to Java Bean mapper that recursively copies data
from one object to another. Typically, these Java Beans will be of
different complex types.
Dozer supports simple property mapping, complex type mapping,
bi-directional mapping, implicit-explicit mapping, as well as
recursive mapping. This includes mapping collection attributes that
also need mapping at the element level.
Look at this: http://dozer.sourceforge.net/
It's a great JavaBean Mapper.
Here the "Getting Started":
http://dozer.sourceforge.net/documentation/gettingstarted.html
Perhaps you can write your own Annotation class in order to create the relationship between the classes. So, for example
public Class Person{
#MyAnnotation(id='name')
String name;
#MyAnnotation(id='addr')
String address;
#MyAnnotation(id='desc')
String description;
}
public Class PersonFacade{
#MyAnnotation(id='name')
String name;
#MyAnnotation(id='addr')
String address;
#MyAnnotation(id='desc')
String desc;
}
Then in your TransformClass, you simply need to iterate through the annotations, find a match and set the corresponding field value with the help of Reflection.