add property for a object dynamicly - java

Hi:
In our application,we have retrive some data from the database,for example,the table have columes:id,name,age,address,email.
Then we will get some of these propertis according to the client.
If client need the id, name, we get the id name, if client need id, name, age, we get the id, name, age.
Now we want to create a class to wrap these properties. However we do not know exactly which field are requested.
String[] requestPro={"name","id"}; //this field is specified by client
Map<String, Object> map=new HashMap<String, Object>();
Entity en=Entity.newInstance();
for(String p:requestPro){
map.put(p, BeanUtils.getProperty(en, p));
}
Here can I replace the map with a Class?

If I understand you right, you want to dynamically add properties to a class, or rather: to a specific instance of a class.
The former is possible e.g. in Groovy, where there is a metaclass object for every class, to which you can assign behavior at runtime, the latter is possible in JavaScript, where you can assign behavior both to an object's prototype and to an object itself. But neither of those versions is possible in Java, so using a Map or a similar structure is the thing to do in Java.

Related

decoupling object construction tied to input data

What I'm doing
I'm using Dependency Injection to decouple my classes.
How I'm trying to do it
The class I am making constructs ObjectImplementation (the interface) Objects to hold data and it acts as a sort of container. I'm doing this to parse data and cross reference two data-sets. My problem is that I currently have object construction tied to the data being formatted a certain way. I am using the Factory pattern and a properties file "config.properties".
What I want to be able to do
I want to be able to have the factory take in an array of fields or some other similar type and be able to construct instances of the reflected object type without dependencies on the data. In this case they are Salesrep instances but other times I want to construct Salesrep instances or other classtype instances with different fields filled and different ones null without formatting the data to contain the names of fields.
The end goal
The point is so that I can construct different objects with the same container code. If I want to contain the objects differently I'll simply make a new implementation of the parent interface of this container class.
What I'm thinking is the problem
I've figured out that a Fieldmap was a good idea through previous versions of this question and my own research. Yet there is no way to actually set those fields without having something in the data to match to the Fieldmap
Extra Clarification
I really want to know if I can find a way to achieve my goal without adding field names to the data
//creates new properties object and loads in the file configuration
Properties prop = new Properties();
prop.load(SalesRepbyId.class.getResourceAsStream("config.properties"));
//reflects in the class we wish to use
Class<? extends ObjectImplementation> Classtouse = Class.forName(prop.getProperty("ObjectImplementation")).asSubclass(ObjectImplementation.class);
//initializes the data and some hashmaps to store the data or the methods of the reflected class
ArrayList<String[]> Salesrep_contactlist = FileParser.ReadFile();
Map<String, ObjectImplementation> SalesrepByIdMap = new HashMap<>();
Map<String, Method> MethodMap = new HashMap<>();
//adds in the data (fields) by constructing objects of the reflected type using the ObjectImplementation interface
for (String[] fieldarray : Salesrep_contactlist) {
ObjectImplementation object_to_add = null;
try {
//utilizes the factory pattern to return an instance of the reflected class
object_to_add = Factory.getObjectImpl(prop.getProperty("ObjectImplementation"),fieldarray);
/**
uses a method hashmap to map the name of the method to the Method object.
I did it this way because dynamic variable declarations are not possible and
I wanted to decouple Method declarations from the specific class that has
them. If i just hardcoded in which methods I get from the implementing class
that introduces extra dependencies I don't want.
**/
for (Method method:Classtouse.getMethods()) {
MethodMap.put(method.getName(),method);
}
//same as above but for fields this time
for (Field field:Classtouse.getFields()) {
FieldMap.put(field.getName(),field);
}
//object_to_add is a String[] with the format [Fieldname1:fieldinput1,Fieldname2:Fieldinput2]
//so I want to get this array and get each element, seperate the fieldname and then use that string to access the actual Field object of the same name in FieldMap
String fieldname = object_to_add.get(0).split(":").get(0)
String fieldinput = object_to_add.get(0).split(":").get(1)
Field name_example = Fieldmap.get(fieldname)
name_example.set(String.class,fieldinput)
//This requires the data to have the fieldname in it rather than just the fieldinput (or data). Also it confines the input to be strings because I don't think I can use a generic type to set this field even though potentially I would want to.
There is no way for me to dynamically set Field types without something to go off of in the data or elsewhere. In order to avoid something hard coded like: Salesrep rep = new rep (arg1,arg2,arg3 ...) I needed to use the Fieldmap and be able to match the data coming in to what fields I wanted to set. Since I didn't want to do it by order ex:
List list = new list("bob","800-352-4324","foo#example.com");
int i = 0;
for(i = 0, i > list.size(), i++){
Field field = new Field(//need a name here automatically rather than hardcoded)
field.set(object_to_add,list[i])
i++
}
The above didn't have any reference to the actual name of the Field that I actually use in my class. I didn't want that and then it dawned on me that the first line of my data (which is in CSV format) has the Field names effectively listed. ex:
(in the CSV File) foo.txt:
1: name,phonenumber,email
2: "bob","800-352-4324","foo#example.com"
3: "steve","800-444-4444","annoyingcommercials#example.com"
4: ...
Using this knowledge My solution is to use the first line of my data to specify the field names and their order so that when I take in lines as an array of these strings I can use the first line array as a reference to how to set the fields. I will know that the first element in the array should be the name the second should be the number ect ect. This way I only have to change the first line if I want to change how many fields the data holding class actually has.
puesdocode:
ObjectImpl. Classtouse = refelct in the class to use here from properties file
List(String[]) fieldarray = the raw data taken in and converted to a list of string arrays
String[] firstline = fieldarray.getfirstline()
List(String[]) restoflines = fieldarray.getallotherlines()
for i = 0, i > firstline.size(), i++{
Fieldmap.put(Name of the field from firstline[i], create a new Field object here with the Name);
Field fieldtoset = Fieldmap.get(Name of the field again)
fieldtoset.set(make an instance of the Classtouse here, restoflines[i] which represents the data in the 'Name' column)
}
For some silly reason I had it in my head that there was a way to do this without any change to the data, as if the Factory which created the object could take in arbitrary/generic arguments and somehow just know where each field went. I realized that that was silly because I needed to tell the code how to actually set the fields but In a way that it wasn't hard-coded into the class. This solution puts the dependency on the data so now its not hard-coded into the class. I should have seen this sooner.

A proper way to make an HashMap with multiple value type

I have an object the represent an entity. By example i have the "user" java object that have the followings field, String name, String first name, String address, boolean deadOrAlive. But now instead of having field i want to put them into a hashmap, so my first reflex was to make it this way :
private HashMap<String, Object> fieldsHM;
This would means that i have to cast my HM value when i want to use it and i don't want to make that because i need to know the type before i use my value. I want to make something like :
Set<String> keys = fieldsHM.keySet();
for(String key : keys) {
if(fieldsHM.get(key).isBoolean()) {
// Do the appropriate things
} else {
// Do the thing for this case...
}
}
I think it's possible in java, would this be good to do it this way ?
EDIT 1: I don't want to make a hashMap because this is not what i need. What i need is a way to browse the fields of the Entity user fields by fields, and depending the type of the field do the appropriate things.
I don't want to make a hashMap because this is not what i need. What i
need is a way to browse the fields of the Entity user fields by
fields, and depending the type of the field do the appropriate things.
I guess that would be a job for Reflection, like User.class.getFields().
It will still be uncomfortable to distinguish between primitive field, but you could use their wrapper classes instead.
But whatever path you choose, I think there would be a better solution if you would state what the actual goal is.
Depending on your actual use case, it might make sense to use JSON (maybe with databind) or even a database.
You could use the heterogeneous container pattern, but I would abandon the map idea and use a proper object.

Which collection should I use to easely get certain object from it by the pair of properties?

Info about network interfaces comes from several servers and must be shown in the table. Each interface must have name and serverName, they're not unique, but pair of them is.
Problem: Information comes every second, and I need to update fields of each interface with new data. So I need to get certain (identified by name and serverName) interface from some list with minimum effort (resources). Table works only with observableList, but searching through it is the overkill. It can contain thousand of interface objects.
Should I create own realization of list, which can be flatten to observableList, or the best way will be to hold HashMap<String, NetInterface> of each server (key is interface's name) with refences from observableList?
HashMap>
use as auto increment for Integer.
The best way will be using the unique thing(name+server name) as the key of your Hash Map.
Use a Map<String, Map<String, NetInterface>, where the outer key is the name and the inner key is the server name.

Is there a possibility to keep a single map store and use for multiple maps in hazelcast

Currently am using Hazelcast and persistence database as Hbase,
So far I have 10 maps, for each map am using a map store, So Am using 10 mapstore classes (i.e) In all the 10 classes am implementing the MapStore. It creates a complexity in maintenance.
So What I did is, I kept a generic map store and implemented the same class for all the maps, It has the ability to accept it, To make it clear, I did something like
Map1 - com.test.GenericMapStore
Map2 - com.test.GenericMapStore
Map3 - com.test.GenericMapStore
...
Map10 - com.test.GenericMapStore
It gets mapped as above,
But for the methods in store, storeAll, loadAllKeys, loadAll am able to check the instance of object and find the mapName ---- Not a good way
But for methods like delete, deleteAll, load - I dont have any clue to find the mapName,
Pls tell me like any way to use a singleMapStore for all the maps???
So I need a map store implementation where, for all methods in mapstore, I need the PARAM called mapName to be passed, So In case, If I have common Implementation, I can make use of it just by using MAP NAME param in all the methods,
Example :
Store(String key, Object object, String mapName),
StoreAll(Map, String mapName),
delete(String key, String mapName)
delete(Collections keys, String mapName) ...
If there is a way already available, Pls do let me know...
Thanks hazelcast team,,, You ppl are doing the great job... Much Apprecaiated...
Thanks and Regards,
Harry
You should be able to achieve this with a MapStoreFactory (docs).
The MapStoreFactory is called with the name of the map and you can pass that name into the GenericMapStore.
In you MapStoreFactory :
public MapLoader newMapStore(mapName, props) {
return new GenericMapStore(mapName);
}
then in GenericMapStore you will have the mapName for each operation.

Using a String as an identifier when creating a new Object

I have a String eg:
1,TSM,501,SM0156,John Thorne,BCO200,24,30,2,CSM,500,AC1157,Peter Jones,BCO104,24,60,...
The string represents a list of people within a department.
The "SM0156" & "AC1157" are their unique identifiers within the department
I would like to loop through the string and create a new 'person object' every time I meet an identifier. The object is then stored in an ArrayList. I believe I could do this with the following code:
deptList.add(new = PersonDetails());
This creates my object but I want to be able to reference it later possibly by the unique identifier! Whilst looping through the original string i have extracted out the identifier in this case "SM0156". I was hoping there was a way to then use this as the reference to the object EG
PersonDetails "SM0156" = new PersonDetails();
deptList.add("SM0156");
Obviously here "SM0156" represents a string but surely I could convert it somehow to use as an reference to my new PersonObject??
Thanks for any help in advance..
You do not want to attempt this. Store your details in a collection and depending on the collection you should use it accordingly.
If you choose an ArrayList, make sure your PersonDetails class has a field Id which you can look up (or create a new class that holds an Id and a PersonDetails object).
Another solution is creating a Map<String, PersonDetails> to map the Id to the person.
Try to use HashMaps. HashMaps stores the objects with key/value principal.
http://www.mkyong.com/java/how-to-use-hashmap-tutorial-java/
You can use a Map<String, PersonDetails>.

Categories

Resources