Is it possible to create new variables in java dynamically.
class A {
methodA(String variableName) {
}
}
So if new method is called twice, 2 new variables should be newly added to this class?
Is it possible?
No. Have you considered storing a Map<String, Object> in the class instead? The keys in the map would be the "variable names" and the values in the map would be the logical variable names.
If you could give more information about what you're trying to achieve (from a high-level perspective) that would help.
No, this is not possible to do in Java.
The fields in a class is determined at compile time and can't be changed during runtime (except though sophisticated techniques such as class reloading though for instance JRebel). I would however not recommend doing this, unless you're writing some IDE for instance.
A class and its members are defined and then compiled to bytecode, so they cannot be readily modified at run-time. That said, there are a number of libraries out there, such as cglib, which provide runtime modification functionality. This page can tell you more: http://java-source.net/open-source/bytecode-libraries
(This is not to say that runtime modification is the right thing to do!)
In a good design, a class must represent something, semantically speaking. You design it to represent an object in your system.
If you want to add more things to a design in run-time, well, something's not quite right -- unless, of course, the design needs adding information in run-time, and there are tons of data structures just ready for the job!
Check out Maps in Java, for example.
Following is the way that i have implemented and helped me to fix my solution easily without much hurdles.
// Creating the array List
List accountList = new ArrayList();
for(int k=0;k < counter;k++){
accountList.add(k, (String)flowCtx.getValueAt("transitId"+m));
}
Iterating the loop and adding the objects into the arraylist with the index.
//Retrieving the object at run time with the help of the index
String a = accountList.get(i));
Using a HashMap could be a solution. For example, if we have the following class:
class Staff {
private HashMap<String, Object> mylist = new HashMap<String, Object>() ;
void setNewVar(String s, Object o) {
mylist .put(s, o);
}
HashMap<String, Object> getVar() {
return mylist;
}
}
I can use it as:
staff.setNewVar("NumVars",11);
staff.setNewVar("NumBatches",300);
...
and then:
staff.getVar()
wherever you need. I use it to convert some variables (the number can change) to JSON, successfully.
Related
I have seen some people using the topmost parent class as a variable type to hold the child instance and some people use just parent class only. For example:
Collection obj = new ArrayList();
Or
List obj = new ArrayList();
Here, List comes under the Collection only then can’t we use above first line instead of second?
Again, we can't use everywhere in collection framework the reference variable of Collection class only to hold any instance of the class under Collection?
Is this a good practice?
So, I wanted to know which comes under the best practices and why?
If someone could justify technically like performance concerns etc. would be greatly appreciated.
It really really depends on your needs. In your example it doesn't really changes much for basic needs but if you inspect the two interfaces there are some changes. Look :
https://docs.oracle.com/javase/7/docs/api/java/util/Collection.html
and
https://docs.oracle.com/javase/7/docs/api/java/util/List.html
We can notice that the List gives you access to methods Collection doesn't.
set(int index, E element) for instance is defined in the List interface and not in Collection.
This is because every classes inheriting from Collection don't need to implement all the same methods.
Performance wise it have no impact.
Always use the top-most parent class that have all the functionalities you need. For your example there is no need to go higher than List .
There is no so called "best practice" for choosing the class to be used for the reference type. In fact, the class in the highest hierarchy is the Object class. Do you use Object as the reference type for everything you do? No, but generally you may choose the higher class with the all the methods available for your needs.
Instead of following the so called "best practice", apply what suits best for your situation.
These are some pros and cons for using higher hierarchy classes as reference type:
Advantage
Allows grouping of object which shares the same ancestor (super class)
Allows all instances of the given class to be assigned to it
Animal dog = new Dog();
Animal cat = new Cat();
Allows polymorphism
dog.makeNoise();
cat.makeNoise();
It is only an advantage when you are accessing common behaviours or members.
Disadvantage
Requires casting when you are accessing behaviours which exist in one object but not the other.
dog.swim(); //error, class Animal do not have swim()
((Dog)dog).swim();
As you start dumping various objects in the common parent class, you may have a hard time trying to figure out which members belongs to which class.
(Cat(cat)).swim(); //error, class Cat do not have swim()
The general idea is hiding as much as you can so things are easier to change. If you need indexing for instance (List.get(int index) then it MUST be a list because a collection does not support .get(index). If you don't need indexing, then hiding the fact you're using a list, means you can switch to other collections that might not be a list later without any trouble.
For example, maybe one month later I want to use a set instead of list. But Set doesn't support .get(index). So anybody who uses this List might use the indexing features of a list and it would make it difficult to switch to a set because every where someone else used .get(), would break.
On the other hand, excessively hiding your types can cause accidental performance issues because a consumer of your method didn't know the type. Suppose you return a List that's actually a linkedlist (where indexing is O(n)). Suppose the consumer of this list does a lookup for each entry in another list. That can be O(n*m) performance which is really slow. If you advertised that it was a linked list in the first place, the consumer of the linkedlist would realize that it's probably not a good idea to make multiple indexes into this list and the consumer can make a local copy.
Library code (suppose the one you're designing)
public class Util {
public static List<String> makeData() {
return new LinkedList(Arrays.asList("dogs", "cats", "zebras", "deer"));
}
}
Caller's code (suppose the one that's using your library or method)
public static void main(String [] args) {
List<String> data = Util.makeData();
int [] indicesToLookUp = {1,4,2,3,0};
for( int idx : indicesToLookUp ) {
if(idx < data.size()) {
// each index (LinkedList.get()) is slow O(N)
doSomethingWithEntry(idx, list.get(idx));
}
}
}
You could argue it's the caller's fault because he incorrectly assumed the List is an ArrayList<> and should have made a local copy of the list.
protected static final Map<String, Integer> m = new HashMap();
I have a question in regards to performance of using the above. I am creating a 2D Tile Engine for a simple RPG game. I am using the hash map above to store the name of a tile along with its respected color code (Ex: 0xff00ff21). Since this is a game, the code m.get("name");is called an enormous amount of times to check if a tile is updated or not. (Ex: The render method with my computer runs at about 850 times per second). Please also note, I made sure to declare the HashMap outside of any loops and that it is initialized via a method call(also static) through the constructor that m.put("name", value) inputs all the information.
1) Is using a HashMap in this way a good idea? Is there perhaps another way to go about this more efficiently.
2) Is using a static final implementation of a hashMap good practice? The values will never change and the values used will be needed within the super class and its sub classes (Hence the "protected"). Can I set the key and value variables to final as well?
3) I understand that HashMap doesn't allow for duplicate keys, but from tinkering around with the HashMap, by inputting two of the same keys it simply replaces the older key and value with the newest .put("name", value);Is there to a way to throw an error perhaps if you try to .put("water", 0xff00ff21) and .put("water", 0xff221133) and/or .put("water",0xff00ff21)
Thank you for your time. New to this community and looking forward to helping/getting helped.
Please note that it is bad to ask three questions in one post.
1) IMO, yes. I usually use a HashMap for this kind of things. This can clarify things a lot better and enhance the readability of your code. Just imagine if you you only use hex color values for these kinda things, I think a lot of people would ask you what is 0xff221133 and what is 0xff00ff21.
2) Yes it is! static final is used when you want to declare some kind of constant. However, declaring a hash map as static final doesn't mean that its content cannot be changed. To prevent this, encapsulate the map in a class and only provide get methods:
final class TileColorMap {
private static final HashMap<String, Integer> tileColorMap = //blah blah blah
static {
//Add things to your map here
}
public static int get(String key) {
return tileColorMap.get(key);
}
}
3) If you look at the docs, specifically, Hashmap<>.put, you will see that:
Returns: the previous value associated with key, or null if there was no mapping for key. (A null return can also indicate that the map previously associated null with key.)
So you can add a method that put something into the map and will throw an exception if the key is a duplicate by checking whether the returned value is null.
private static void putStuffInMap (String key, int value) {
Integer returnedValue = tileColorMap.put(key, value);
if (returnedValue != null) {
throw new RuntimeException("Duplicate Keys!");
}
}
1) I'm not sure I understand what you're doing here, but how many different kinds of tiles could you be using here? You might be better off just defining a Tile object with a few constant Tiles that you can just reuse again and again by referring to Tile.WATER, etc instead of doing a hashtable lookup. If water has multiple colors just put them all in the water Tile object and pick from amongst them.
public class Tile
{
public static final Tile WATER = new Tile(...);
public static final Tile ROCK = new Tile(...);
}
2) Making a hashmap instance static and final doesn't make it immutable. The contents can still be updated. There's no performance benefit anyway. A read only hashmap wouldn't be any faster than a writable one. If you don't want it updated, just don't update it. It's your code, it's not like it's going to write to the hashmap when you aren't looking.
3) You could subclass hashmap and make it not accept duplicate keys, but again, I'm not sure what the purpose of this is- why aren't you sure what colors your tiles will be at run time? This strikes me as the kind of thing decided before compile time.
Using HashMap should be efficient enough. Is there more efficient way? Of course there will always be but whether it is appropriate depends on your design. For example, if tiles are statically defined, you may use enum/integer constants to represent a tile (instead of using "name"), and your tile-to-XXX mapping can be easily expressed as ArrayList or even array. (Again, it may not be appropriate to your design).
Again it depends on the design. Are the class containing the map something that is going to instantiate multiple times but you really want each instance to share same mapping? Are you going to give flexibility to the child class to set up the mapping? It is only meaningful to make it static if first answer is YES and second is NO.
To avoid change of content for the map, you can wrap it in a unmodifiable map:
// Access your data through this, so you won't mistakenly modify it
protected final Map<...> tileColorMap = Collections.unmodifiableMap(getTileColorMap());
// your super class or sub-class is providing the actual map
protected Map<...> getTileColorMap() {
Map<...> tileColorMap = new HashMap<>();
// do your setup
return tileColorMap;
}
If you are using Java 8+, it may be better to use Map#merge() method, and have the remapping function throw an exception you desire. Compared with the approach given by other answers, using merge() is safer as original value won't be mistakenly replaced. You may also selectively throw the exception if the new value is different from existing value.
I wish to create an instance of TreeMap whose keys will be of type String and values of
type ArrayList <String>:
Map<String, List<String>> directory = new TreeMap<String, List<String>>();
String[] names = {"Anne","Ben","Charles","Dawn","Edward"};
for (int i = 0; i < names.length; i++) {
directory.put(names[i], new ArrayList<String>());
}
My question here relates to line 5 of the following code. Is it acceptable/best practice to pass an anonymous object (in this case given by new ArrayList()) as the actual argument to the put() method? My rationale for this is that by the nature of a map, these objects can still be reached by the following for example:
directory.get("Anne");
I don't see anything wrong with that. As a matter of fact, I don't even see a reason to call such a thing "anonymous". You are simply avoiding declaring a variable (i.e. a reference to that object - you are still creating the object) that you are never going to use anyway.
There is no such thing as an "anonymous" object in Java. There are anonymous classes, i.e. classes that don't have a name. An object has no concept of a "name". It is simple referred to by one or more references as needed.
Nothing wrong with that at all. I use it all the time.
In your code you create a new ArrayList object for every one of those names. Is this what you wanted to do? Whether it is best practice depends on what you are trying to do, it would be best practice to store e.g. the names of the pets these people own (a list of pets for every person).
Edit: I've gotten a couple of answers that say what I already said in the question. What I am really interested in is finding corroborating reference material.
I am looking at a code sample that more or less follows this pattern:
Map<String, List> getListsFromTheDB() {
Map<String, List> lists = new HashMap<String, List>();
//each list contains a different type of object
lists.put("xList", queryForListOfXItems());
lists.put("yList", queryForListOfYItems());
return lists;
}
void updateLists() {
Map<String, List> lists = getListsFromTheDB();
doSomethingWith(lists.get("xList"));
doSomethingWith(lists.get("yList"));
}
My feeling is that this is an anti-pattern. What the coder should have done is create a class which can be returned, like this:
class Result {
private final List<X> xList;
private final List<Y> yList;
public Result(xList, yList) {
this.xList = xList;
this.yList = yList;
}
public List<X> getXList() { xList; }
public List<Y> getYList() { return yList; }
}
This would be more type-safe, avoid over-generalizing a very specific problem, and be less prone to errors at runtime.
Can anyone point me to any authoritative reference material which specifies that you should avoid this kind of pattern? Or, alternately, if it's actually a good pattern, please give justification.
I think the point is the number of Lists is fixed. Since you ensure the code uses 2 lists, the map is a little bit over-generalizing.
So 'class Result' is better I think.
I say it depends on the context.
If you return a map, the caller has to know the 'magic' keys "xList" and "yList" to get the actual data out of the map. I mean magic as magic constants. (You could iterate over the map to find the magic keys, but that's just a trick.) By using the map you have actually hidden the data, making it harder to get what one wants (x- and yLists).
The magic constants do not have to be so magically. If "xList" and "yList" would be the table names in the database (or whatever external strings), then I would expect to get a mapping from table names to object lists. Someone might add/rename/delete tables. (Or, maybe prettier, I would like to be able to query per table like getListFromTheDB("xList");. )
In your code you got this method
queryForListOfXItems();
That does smell like hard coded xList and yList. That would thus (IMO) make a map a bad choice.
I agree with you.
Obviously the guy was lazy and used a Map to avoid creating a new class.
The side effect is that the code that need to use getListsFromTheDB() will be less readable, and, as you mentionned, more error-prone.
Of course, there is the alternative in which the caller creates the lists:
void fillFromTheDB(List<X> xList, List<Y> yList) {
//each list contains a different type of object
xList.addAll(queryForListOfXItems());
yList.addAll(queryForListOfYItems());
}
void updateLists() {
List<X> xList = new ArrayList<X>();
List<Y> yList = new ArrayList<Y>();
fillFromTheDB(xList, yList);
doSomethingWith(xList);
doSomethingWith(yList);
}
I don't have any authoritative material, but my gut feeling is that, unless there's something more complex going on in the real code, using a Map this way doesn't bother me. The Result class feels a bit like overkill, actually.
I'm working on a java program, and I have several vectors defined and filled (from a file) inside a method. I need to return the contents of all the vectors from the method. I have heard you can put them all in one object to return them. Is that possible, and if so, how? If not, do you have any possible solutions for me? Thanks in advance for your help!
Here is a code snippet:
Object getInventory()
{
Vector<String> itemID=new Vector<String>();
Vector<String> itemName=new Vector<String>();
Vector<Integer> pOrdered=new Vector<Integer>();
Vector<Integer> pInStore=new Vector<Integer>();
Vector<Integer> pSold=new Vector<Integer>();
Vector<Double> manufPrice=new Vector<Double>();
Vector<Double> sellingPrice=new Vector<Double>();
Object inventoryItem=new Object(); //object to store vectors in
try
{
Scanner infile= new Scanner(new FileReader("Ch10Ex16Data.txt"));
int i=0;
while (infile.hasNext())
{
itemID.addElement(infile.next());
itemName.addElement(infile.next()+infile.nextLine());
pOrdered.addElement(infile.nextInt());
pInStore.addElement(pOrdered.elementAt(i));
pSold.addElement(0);
manufPrice.addElement(infile.nextDouble());
sellingPrice.addElement(infile.nextDouble());
i++;
}
infile.close();
System.out.println(itemID);
System.out.println(itemName);
System.out.println(pOrdered);
System.out.println(pInStore);
System.out.println(pSold);
System.out.println(manufPrice);
System.out.println(sellingPrice);
}
catch (Exception f)
{
System.out.print(f);
}
return inventoryItem;
}
Personnally, I'd scrap that approach completely. It seems like you need a Product class:
public class Product {
private String itemName;
private int itemID;
// etc etc
public Product(String itemName, int itemID) {
this.itemName = itemName;
this.itemID = itemID;
// etc etc
}
public String getItemName() {
return itemName;
}
public int getItemID() {
return itemID;
}
// etc etc
}
Then something like this :
public class Invertory {
private List<Product> products = new ArrayList<Product>
// etc etc
public Inventory(String fileName) throws IOException {
// Load file,
// Read each product,
products.add(new Product(...product arguments); //add to array
}
public Product[] getProducts() {
return products.toArray(new Product[]{});
}
}
First of all, use ArrayList instead of Vector. Then use a Map as your return object, with each value of the entry is one of your Lists.
Second of all, a much better approach is to create an object that actually holds each of your fields and return a java.util.List of these objects.
public class Item
{
String id;
String name
Integer pOrdered;
Integer inStore;
:
:
You're doing a few things wrong.
Firstly, don't use Vector. Like, ever. If ordering is important to you, you want List on the API (and possibly ArrayList or LinkedList as an implementation).
Secondly, you're trying to have a large number of arrays have values that happen to line up. That's going to be nearly impossible to use. Just create a class that represents one record, and return the List of those.
Thirdly: do not catch that exception. You don't know what to do with it, and you're just going to confuse yourself. Only catch an exception if you have a really good idea what to do in the error case (printing out an error message without a stack is just about never the right thing).
The signature of your method is the most important part. If you get that right, the implementation doesn't matter nearly as much. Aim for something that looks like this:
List<Item> getInventory(File input) throws IOException {
}
You really should reconsider your design here. You have multiple vectors, each with properties of the same type of thing — an item in your inventory. You should probably turn this into a single class, perhaps InventoryItem, with members for the name, price, etc. Then, when reading in each item, you construct an InventoryItem with the given properties, and return a single Vector<InventoryItem>.
If you're really attached to keeping track of all those individual Vectors, you could just return a Vector[] with all the vectors you have:
return new Vector[] { itemID, itemName, pOrdered, pInStore, pSold, manufPrice, sellingPrice };
Also, as Robin says, you should use the ArrayList container instead of Vector. The only thing that will change is that you need to change all calls to someVector.AddElement to someList.add.
Sounds like this should be tagged "Homework".
Okay, first of all, are you required to use all these Vectors, or is that your own decision? Though some may point out that using ArrayLists is better, I'd do away with them and create your own Item class.
This way, instead of having a conceptual item's properties distributed across multiple Vectors (the way you're doing now) you have 1 Item instance per item, with fields for all the data relevant to that item. Now, you only need one data structure (Vector or ArrayList) for all your item objects, and you can return that structure from getInventory().
The easiest way to declare the object would be something like
List<Vector<? extends Object>> inventoryItem = new ArrayList<Vector<? extends Object>>
but this has several problems, namely that Java's generics aren't reified, so you have to test and cast the contents of each vector that you get back. A better solution would be to define a container object that has each of the Vectors as fields and add to those.
However, this looks like it is really missing the point. Instead, you should define an InventoryItem who has each of your seven fields. Each time you read an object from the file, instantiate a new InventoryItem and populate its fields. Then, you add this to a single Vector.
Also, it is generally recommended that you do not use the Vector class. Instead, you should use ArrayList. Vector should really only be used if you need its synchronization properties, and even then you should consider wrapping some other list in a Collections.synchronizedList().
Finally, the places where you would want to catch just an Exception can be counted on one hand. You should really be catching an IOException and even that you might want to consider just rethrowing. Also, you should call printStackTrace() on the exception rather than System.out.println().
I find that a good rule of thumb is that it's never really a good idea to pass collections around outside your objects. They are obviously useful inside your object, but outside you lose control and they are not obvious.
Consider the principle of making your code readable instead of documenting it. If you take a collection, how does that tell the caller what to pass in? Even if you use generics, there is no way to assert control over what happens to the collection--someone could be adding to it and deleting from it in another thread after it's passed to you.
There is no reason not to create a business class that contains your collections along with the business logic to manipulate them (yeah, there is always business logic--it's the copy and paste code you'll find around the locations that you access the collection).
I used to find it frustrating that the JDK always seems to take arrays of built-in types rather than collections, but it makes a lot more sense after coming to terms with the idea that passing collections (like passing around any basic type) is just not a very good idea.
While in general I heartily agree with the advice to use List/ArrayList instead of Vector, it is important to know why. Indeed, I have to vehemently disagree with Dustin who says not to use Vector "ever".
A Vector is in essence a synchronized ArrayList. If you truly need synchronization, by all means then, ignore Dustin's admonition, and use Vector.
There is another instance in which Vector is justified. And that is when you need to maintain compatibility with a pre-Java2 code base.