How do I create a variable within another variable? [duplicate] - java

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Dynamic Variable Names in Java:
Let's say I have a string, as below.
String s = "Hello";
Now, I want to create a string, but the string's variable will be called "Hello". In order to make the string's name "Hello", I must access string s to get the name "Hello", so I can use it as a variable name. Below is what I want to see.
String Hello = "I want to do this, But from Accessing String s So I KNOW that String s = Hello";
Thank you for the effort, and please try to explain to me because I am a Java beginner. :D

What you are attempting to do is add a layer of indirection. You cannot access variables dynamically in a static language such as Java/C/C++/Pascal/etc
What you can do is emulate the dyamic context that dynamic languages use by, eg creating a Map to hold the variable names and values in this case you would have
Map<String,String> stringVars = new HashMap<String,String>();
// set a "variable"
stringVars.put("Hello", "value");
// get a "variable"
System.out.println(stringVars.get("Hello"));

Using Reflection (not recommended):
public class MainClass
{
public String Hello = "I want to do this, But from Accessing String s So I KNOW that String s = Hello";
public static void main(String[] args) throws Exception
{
MainClass m = new MainClass();
String s = "Hello";
String result = (String) MainClass.class.getField(s).get(m);
System.out.println(result);
}
}
OUTPUT:
I want to do this, But from Accessing String s So I KNOW that String s = Hello
Instead, use a map as others illustrated.

It is not possible in java.
The only thing you can do is to use A map interface' implementation, for example a HashMap. Using a put method you can 'assign' a value to a given 'name'. The name would be a key and has to be unique within a map, just like variable has a unique name within it's scope.
To retrieve the value, call get method passing appropriate key (ex. string 'Hello') as an argument.

In Java you cannot obtain the variable(reference) name which is pointing to an object since the object has no knowledge of the reference to it and there can be more than one variable refering to the same object.
On the other hand you could do somtething like this; but I do not know how would help:
String s = "Hello";
Reference<String> hello = new SoftReference<String>(s);
String myStringAccessedWithHello = hello.get();

Could you use a Map which takes a string (such as "Hello") and maps it to another String (such as "I want to do this, But from Accessing String s So I KNOW that String s = Hello"). Something like the following:
Map<String, String> stringMap = new HashMap<String, String>();
stringMap.put("Hello", "I want to do this, But from Accessing String s So I KNOW that String s = Hello");
Then you can find all of the key values in the map (such as "Hello") by calling:
Set<String> stringKeys = stringMap.keySet();
and you can lookup the long string belonging to the key "Hello" like this:
String longValue = stringMap.get("Hello");
This is how I would use a simple String value to find an unwieldy String value. Bear in mind you could also use a Map which maps String values to any other type of object.

Related

How to access dynamiclly variables from another Java Class?

My question similar to others but it's little bit more tricky for me
I have a Class DummyData having static defined variables
public static String Survey_1="";
public static String Survey_2="";
public static String Survey_3="";
So, i call them DummyData.Survey_1 and it returns whole string value. Similarly do with DummyData.Survey_2 and DummyData.Survey_3
But the problem is when i call them Dynamically its not return their value.
I have a variable data which value is change dynamically like (data=Survey_1 or data=Survey_2 or data=Survey_3)
I use #Reflection to get its value but failed to get its value
I use methods which I'm mentioning Below help me to sort out this problem.
Field field = DummyData.class.getDeclaredField(data);
String JsonData = field.toString();
and
DummyData.class.getDeclaredField("Survey_1").toString()
but this return package name, class name and string name but not return string value.
What I'm doing can some help me??
Getting the value of a declared field is not as simple as that.
You must first locate the field. Then, you have to get the field from an instance of a class.
Field f = Dummy.class.getDeclaredField(“field”);
Object o = f.get(instanceOfDummy);
String s = (String) o;
Doing the simple toString() of the Field will actually invoke the toString() method of the Field object but won't access the value
You must do something like this:
Field field = SomeClass.class.getDeclaredField("someFieldName");
String someString = (String) field.get(null); // Since the field is static you don't need any instance
Also, beware that using reflection is an expensive and dangerous operation. You should consider redesigning your system

How to make a reference to the Variable in java and not to the Type of it

I have a specific question, so I start with an example:
I have some values of type String saved in variables as follows:
String one = "someValue";
String two = "anotherValue";
String three = "the last one";
and so on. This is of course a simple example, in the fact it will be methods that returns String Type and I save it in Variables to use further in code;
I also have a List of Strings that contains some namespaces, that should be a name of xml-elements:
List<String> namespaces = new ArrayList<Sting>(Arrays.asList("example:org:one", "example:org:two", "example:org:three"); //and so on
It will be seems as
<example:org:one></example:org:one><example:org:two></example:org:two><example:org:three></example:org:three>
in xml - document. But of course they also have some values, which are saved in String Variables ('one', 'two', 'three' respect.) and I would like to make a reference on it in Java code, but explicitly, not implicitly. Say, use as value 'one' -> but not a String 'one', but a Variable, which name is ONE. GOT THE IDEA?:
for(String s : namespaces) {
String[] arrayOfNamespaces = s.split(":");
int lengthOfArrayOfNamespaces = arrayOfNamespaces.length;
xmlBuilder.with(s, arrayOfNamespaces[lengthOfArrayOfNamespaces - 1]);
}
Is it possible? Is there something in java, that make a reference to a variable with the particular name in code: I believe it would be as something like Casting to VAR or as Annotation (maybe somebody had made something like this) :
...
xmlBuilder.with(s, #Var arrayOfNamespaces[lengthOfArrayOfNamespaces - 1]);
Or Mapping is the only way to make it works?

ArrayList modifying value returned by "get" method [duplicate]

This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 6 years ago.
I have below two situations related to ArrayList get method, one with custom class and one with String class:
1. Below is the example of modifying Custom class ArrayList element:
ArrayList<MyClass> mTmpArray1 = new ArrayList<MyClass>();
MyClass myObj1 = new MyClass(10);
mTmpArray1.add(myObj1);
MyClass myObj2 = mTmpArray1.get(0);
myObj2.myInt = 20;
MyClass myObj3 = mTmpArray1.get(0);
Log.d(TAG, "Int Value:"+myObj3.myInt); // Prints "20"
2. And below is the example of modifying String ArrayList element:
ArrayList<String> mTmpArray2 = new ArrayList<String>();
mTmpArray2.add("Test_10");
String myStr1 = mTmpArray2.get(0);
myStr1 = "Test_20";
String myStr2 = mTmpArray2.get(0);
Log.d(TAG, "Str Value:"+myStr2); // Prints "Test_10"
So in case of MyClass ArrayList, when I call get and modify the value, then I see change is reflecting when I do get again.
But same way when I modify String ArrayList, then changes are not reflecting.
What is the different in of the get method in both the scenarios?
Is it that in case of String, String class creating deep copy and returns new object, and in case of Custom class shallow copy is created?
In the first scenario applicable to "LinkedHashMap", "HashMap" and "List"?
Your are not doing the same thing in the two cases.
Here you update the state of an object, so the change affects the object stored in the list :
myObj2.myInt = 20;
Here you are assigning a new object to a local variable, so the list is not affected :
myStr1 = "Test_20";
If String was mutable, you could have modified the String by calling some method, and the change would have been reflected in the object stored in the list :
myStr1.setSomething(...);
On the other hand, if in the first case you would have changed the value of the local variable, the object stored in the list wouldn't have been affected :
myObj2 = new MyClass (...);
Strings are immutable. You're not inserting the new string into the array list.
When you do String myStr2 = mTmpArray2.get(0);, even tho you are pointing to a reference in the ArrayList, any attempt to change the value, will (because of String immutability) create a new String (myStr2) that will not reference the ArrayList anymore.
When you do myStr1 = "xxx", you're not actually changing the ArrayList reference, you're changing a new (copy) (now called myStr1) that was grabbed from the ArrayList and it has a local scope.
Read some more about Strings: Immutability of Strings in Java
Now in the first example, you are pointing to a mutable object (your custom class) so you're literally changing the direct value, through the reference. Welcome to Java. ;)
Unrelated: This code: MyClass myObj1 = new MyClass(10); is (arguably) considered bad. It's better to use a factory pattern that is a lot easier to read. In other words, public constructors with parameters are hard to read (for example, I have no idea what I am constructing when I read your code).
A (perhaps) better approach would be: MyClass myObj = MyClass.createInstanceWithCapacity(10); // i've invented the name because I don't know what your 10 is, but look at both, which one do you think is easier to understand upon first glance?
Disclaimer: The above unrelated comment is my personal opinion and not all developers will agree. ;)
Strings have very nice property called "Immutablity"
This means that String cannot be mutable (changed), when we create/
try to refer to old string, a new instance string is created. And any
changes we do are saved in new instance and it do not affect the old
string
For example,
String s = "Old String";
System.out.println("Old String : "+s); // output : Old String
String s2 = s;
s2 = s2.concat(" made New");
System.out.println("New String : "+s2); // output : Old String made New
System.out.println("Old String is not changed : "+s); // output : Old String
These is no difference between the two "get" calls. The difference is between the types that the ArrayList is holding, and what you're doing the references the "get" method returns.
In your first example, you do this:
MyClass myObj2 = mTmpArray1.get(0);
myObj2.myInt = 20;
Here, you're getting a reference to the MyClass instance in the ArrayList in position 0, and you are modifying a field within this instance.
In your second example, you do this:
String myStr1 = mTmpArray2.get(0);
myStr1 = "Test_20";
Here, you're getting a reference to the String instance in the array list, and then you're giving myStr1 a reference to a different string which you create ("Test_20"). It's as if you did wrote myObj2 = new MyClass(20); in the 2nd line in the 1st example.
So, in short, in the 1st example, you access a field within the object by altering it from the reference you grabbed. In the 2nd example, you simply altered your reference to point at a different String.
I should also mention that in Java, Strings are immutable, meaning once they have been created, they cannot be changed.
String is an immutable class. A line like
myStr1 = "Test_20";
does not change the value of the String object myStr1 is pointing to. Instead a new String is created and myStr1 is modified to point to the new String. The original String is unchanged and can be retrieved from the ArrayList.
Your MyClass object is clearly mutable. Only one instance is created and its state is changed by the assignment
myObj2.myInt = 20;
Hence when this object is retrieved from the ArrayList, its new state is seen.
You simply do NOT change the list in your 2nd example.
In the first example, you are doing this:
Get the first object from the list and store it in the variable called 'myObj2'
Modify the object stored in variable 'myObj2' by setting the int value of this object
But your second example is completely different:
String myStr1 = mTmpArray2.get(0);
myStr1 = "Test_20";
Let me translate that:
Get the first element from the list and store it in the variable called 'myStr1'.
Set the value of the variable 'myStr1' to "Test_20"
So, in case one you are modifying a variable of the object stored in the list. In case two you are retrieving the object stored in the list - and then re-use the variable you stored that retrieved object in and use it for something new - but that does not change the original list, of course.
To modify your list for a type like string, you would need to use set(x, "Test_20").

How to name an array with a variable in java?

I am trying to make a calendar in Java that will store events such as doctors appointment, etc. I plan on storing these events as String arrays, containing the name of the event, the location of the event, and the time of the event. In order to generate new events, however, the arrays need to have unique names which I want to be the date they occur on. To do this, I planned on making a method that would take a new name for the array as a variable and then use that variable as the name of the array (as below):
public static void addInformation(String eventLabel) {
String eventName = JOptionPane.showInputDialog(null,"What yould you like the event to be called?");
String eventLocation = JOptionPane.showInputDialog(null, "Where will this event take place?");
String eventTime = JOptionPane.showInputDialog(null, "What time will this event take place? Input as: \"hours:minutes\" using a 24 hour clock.");
String[] eventLabel = {eventName, eventLocation, eventTime};
events.add(newEvent);
}
When I try this, I get an error saying: eventLabel is already defined in addInformation(java.lang.String)
Is there any way to name an array with a variable using a parameter? Any help would be appreciated. Thanks in advance.
EDIT:
It seems you cannot have a variable variable name. Is there a way to create a unique array each time this method is called?
Use a HashMap. For each entry, set the key using the eventLabel parameter, and value as your array. This way, you will have a name for each of your "arrays" (which will be an entry in the HashMap, in this case).
Your method declaration has eventLabel as type String. You try to redefine it as String[]. Try String[] eventLabelArray.
Hot Licks is correct - you cannot do something like addInformation('Arr') and have eventLabel be named 'Arr' and call Arr[0]. Why do you need it to be variable?
What you are trying to do is like using a variable name to create a variable name, I am not sure if this can be done.
But Maps can be used to solve your problem.Maps will provide your exactly same functionality as you want
for example:
Map<String, Something> myMap = new HashMap<String, Something>();
String name = eventName + eventLocation + eventTime;
myMap.put(name, new something);
eventLabel is used as both a local variable in the method as well as a passed-in argument. Give the two different names and that should fix your problem.
You cannot use the same name as the variable passed (String eventLavel) to your function
public static void addInformation(String eventLabel){
String eventName = JOptionPane.showInputDialog(null,"What yould you like the event to be called?");
String eventLocation = JOptionPane.showInputDialog(null, "Where will this event take place?");
String eventTime = JOptionPane.showInputDialog(null, "What time will this event take place? Input as: \"hours:minutes\" using a 24 hour clock.");
String[] arr = {eventName, eventLocation, eventTime}; // some other name!
events.add(arr);
}
It's good you're thinking about things this way, but I think you're trying to solve a non-problem.
Is there a way to create a unique array each time this method is
called?
Yes, it happens for free - you don't have to do anything. Because the array is being created inside the method, a new one gets created every time. So as others have said, just use a different variable name (not eventLabel) and you're good to go.

Using scanner to create an object identifier?

Is there any way to create the name of an object depending on user input?
eg.
Object scan.nextLine() = new Object();
No it is not possible. There are no dynamic variables in Java. Java variable name have to be declared in the source code during compile time.
If want to store the Object with the user entered values you can try using a Map to save the data as below.
Map<String, Object> objects = new HashMap<String, Object>();
String name = scan.nextLine();
Object obj = new Object();
objects.put(name, obj); // saving the objects in Map
No you can't do this.
I would suggest having a custom class and store the instanceName:
public class MyClass {
private String instanceName;
public MyClass(String instanceName) {
this.instanceName = instanceName;
}
}
MyClass myObj = new MyClass(scan.nextLine());
No. You cannot do that in java. Since you should already have a class defined to create a object of it.
There are some ways you could fake doing this. You could use a map to give the perception of dynamically named Objects. But since you say you are a beginner, the short answer is no. Make sure you know what you are asking for in your example though. Your example is the equivalent of saying:
String line = "foo";
Object line = new Object();
My guess would be that's not what you wanted (and isn't possible).
Given the line
Type variable_name = expression ;
The name variable_name is simply used in the rest of the scope for referencing the outcome of expression. You know that Java is a compiled language, and these names are only useful to the programmer. Once the compiler does its job, it can use a translation table and replace those names with whatever ID it wants.
Since those name don't even exist at runtime, there's no way of choosing the name for a variable at runtime.
However you may need to access an object depending on user input (for example like in PHP variable variables $$a_var). Depending on your context, you may use reflection to access instance members, or a simple Map<String, Object>. Example with reflection:
public class VariableRuntime {
static class Person {
public String first, last, city;
}
public static void main(String[] args) throws Exception {
Person homer = new Person();
homer.first = "Homer";
homer.last = "Simpson";
homer.city = "Springfield";
System.out.println("What do you want to know about Homer? [first/last/city]");
String what = new Scanner(System.in).nextLine();
Field field = Person.class.getDeclaredField(what);
System.out.println(field.get(homer));
}
}
The same with a Map<String, String>:
public class VariableRuntime {
public static void main(String[] args) throws Exception {
Map<String, String> homer = new HashMap<String, String>();
homer.put("first", "Homer");
homer.put("last", "Simpson");
homer.put("city", "Springfield");
System.out.println("What do you want to know about Homer? [first/last/city]");
String what = new Scanner(System.in).nextLine();
System.out.println(homer.get(what));
}
}

Categories