java naming an object from an aspect of another object - java

I am trying to create an object named after an aspect of another object. I assumed that I would need to change count.counts value into a string in order for this to work but I cannot work out how to reference this in creating the new object.
This is the code i have;
String no=Integer.toString(count.count);
BattleCruiser =new BattleCruiser();
EList.add(battle);
count.count++;

An object does not have a name. We give names to variables so that we know what they point to, what they represent.
Dynamically name a variable does not seem very useful, since you need to reference it afterwards. If the reference is dynamic too, then why not use a data structure instead? For instance:
If you're trying to give numbers to your variables, for instance ship0, ship1... then you can use an array ships instead, and access ships[0], ships[1].
If you want more general names that reference objects, you can use a Map<String,Object> instead.

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.

How can i access the inner object values of an object in mvel?

Object obj=account;
here account object contains books as inner object. So how can i access those values in mvel.
I am new to MVEL. So can you please auggest me how to overcome the above issue.
MVEL works on OGNL.
Let say Account.Class has Books.class
1.) Simple object , not a collection
OGNL - account.books.bookName
2.) Complex object, a collection (Account.class has collection of Books.class)
OGNL - account.books[0].bookName
or Take collection out and put one by one.
book.bookName
This is what can be explained simply, otherwise scope of your question is big and not much clear.

Java API design - Pass by Object or Pass By Value

I am designing the service layer of my web application. There are some scenario which I need to get the Orders based on the Product.
When I design the API, should I pass by object or value?
Order order = new Order();
String orderId = "1";
order.setId(orderId);
List<Product> products = getProductByOrder(order);
List<Product> products = getProductsByOrderId(orderId)
Well, i think you are making some mistakes with this concepts, in this two ways you are making references to this objects, order and orderId(since String is an object too.)
But the best approach in this case is using getProductsByOrderId(orderId) because your code will be loosely coupled, since your other layer won't have to know about an Order object, and just know about a string object. If we can pass simpler objects as parameters, we do.
Good example from #Pienterekaak posted as comment:
"In many cases its easier to obtain just an orderid, then a whole order object. (for example, you would include an order id in a REST call, not the whole order object)"
From my experience i would go for:
List<Product> products = getProductsByOrderId(orderId)
With the argument, that for the first call, you need an Order object, and for the second call you just need an id, which is probally easier to obtain.
Actually both of these are passing by value. Java only passes by value. In both of these cases you are passing a reference to an Object (String) or (Order). You are passing as a value the location of memory where this object is (pointer). If you are passing a primitive type like int it passes the value like 1 but if you are passing an object it passes the value of the pointer to the object ie. memory location. In any case you are always passing by value.
If you have a Map storing the Order objects it is actually more efficient to pass the Object itself because you are directly passing the pointer for that object. If you pass the String id of 1 you are passing a pointer to that string then you would have to use that string to look up your Order object which is actually adding more processing then just passing a pointer to the object directly.
OrderId belongs to the concept of an order. If you pass the order id, the product has to know, how an order is identified. That's not loosely coupled.
If you put the method into Order, so you can call a property like
List order.Products
only the Order concept knows, how products and orders are connected, which sounds right to me.
Products shouldn't know anything about orders but orders should know about products.
If you use Hibernate, you could configure it to do it for you with an one-to-many, since orderId is a primary key in your order table.

Creating a deep copy method, Java

I want to make a deep copy method. I seeked help here the other day with this issue, but that was for a copy constructor. Now I need a regular method. I have the code created (nonworking), but I'm just not understanding it completely.
public GhostList deepCopy(){
int length=this.getLength();
GhostList jadeed=new GhostList();
Ghost[] data = new Ghost[length];
for (int i=0;i<this.getLength();i++){
data[i] = new Ghost();
data[i].setX(this.ghosts[i].getX());
data[i].setY(this.ghosts[i].getY());
data[i].setColor(this.ghosts[i].getColor());
data[i].setDirection(this.ghosts[i].getDirection());
}
return jadeed;
}
Now when I create a new GhostList named jadeed, and then under that I create a new data array of ghosts, does it know that data belongs to the jadeed GhostList? I dont see how the two can be associated, even though they should be.
Also, I'm not getting the lengths to match up for the copy and this.object. What is my problem?
You created a new GhostList and a new Ghost array.
You fill in the Ghost array and return the GhostList but the returned GhostList has nothing to do with the Ghost array.
You should add all the new ghosts to the GhostList
First, you mentioned a copy constructor. If you already have that working, then all you need to do in your deepCopy method is:
return new GhostList(this);
Let's forget that for now and get back to the code you posted. You are creating an array named data but you never used it anywhere. Aren't you supposed to assign this array to jadeed? Something like:
jadeed.ghosts = data;
And finally, instead of calling the method deepCopy, it would be better to call it clone and implement the Cloneable interface. Doing this allows everyone to know how to get a copy of your object using a standard interface.
Your GhostList class will have as its data member a reference to the array of Ghost. You've not shown us the class definition, so lets say that member is named foo. Now all you need to do is make the foo reference of the newly created jadeed object refer to the array of Ghost which you've created and populated. You can do it as:
jadeed.foo = data;
before you return jadeed.
If GhostList and everything it's composed of is Serializable, you can serialize the GhostList instance into a byte array and re-read it. It's a few lines of code, unless you use `Jakarta Commons Lang - one line of code:
http://commons.apache.org/lang/api-2.5/org/apache/commons/lang/SerializationUtils.html#clone%28java.io.Serializable%29

Object Id of an object across the jvms?

I have a question on object ID of an object across JVMs. ie Say suppose i have persisted an object created on JVM1, and now I want to use the same object on JVM2.
So how to do that.
Will the object Id of the object same on both the JVM?
If yes for the above question, then what will be the case if the JVM2 has already an object with the objectID same as the one which is persisted.
thanks.
The object won't exist on JVM2 until you deserialize it. There's no concept of a "universal object ID" in Java - if you need an ID for your objects, you'll have to add it yourself. You could add a UUID field to your object; you'd then want to maintain some sort of cache to allow you to spot duplicates.
Are you really sure you need all of this? It may be worth taking another look at the bigger picture and redesigning.
Check out serialization here or alternatively you could use RMI - check out this link
I'm not really sure what you mean by Object Id, if you mean the reference you get printed out when you print out an object with no toString method then, this is not an object ID this is the memory address reference and will be different on each JVM and different on different invocations of the same program.
You could add a UUID to your object to create an unique id.
UUID javadoc
UUID uuid = UUID.randomUUID();

Categories

Resources