Using String to reference value of a different variable - java

I have two variables that I'm trying to compare but the variable names are long and I'm trying to clean up my code, all the code here is just used as an example.
What I want to do is something like this:
if(objectOne.objectTwo.variableName1 == objectTwo.objectTwo.variableName1)
if(objectOne.objectTwo.variableName2 == objectTwo.objectTwo.variableName2)
...
and do this multiple times but every time change the number at the end of the string
but I'm trying to do it like this:
for(int i = 0 ; i < 5 ; ++i) {
String firstString = "objectOne.objectTwo.variableName" + i;
String secondString = "objectTwo.objectTwo.variableName" + i;
if(firstString == secondString)
//more code
}
however this compares the Strings and I'm trying to use the Strings themselves as references to different variables is there any way of doing this?
EDIT: I'm looking to clean up the code but the main problem I'm having is if I had 100 variableNameNumber variables I would have to do 100 separate if statements, I'm trying to do it in a simple for loop as i increments the variable names get updated

It's possible to do with a Map as long as variables name are unique(of course it must be) , as follows:
Map<String, String> args = new HashMap<String, String>();
args.put("objectOne.objectTwo.variableName1", objectOne.objectTwo.variableName1);
args.put(...);
.
.
.
for(int i = 0 ; i < 5 ; ++i) {
String firstString = "objectOne.objectTwo.variableName" + i;
String secondString = "objectTwo.objectTwo.variableName" + i;
if(args.get(firstString) == args.get(secondString))
//more code
}
However, the motivation can be skeptical, as Jon Skeet points out.

You need using java Reflection API here to get the real field value for "objectOne.objectTwo.variableName1", "objectOne.objectTwo.variableName2" and "objectTwo.objectTwo.variableName1", "objectTwo.objectTwo.variableName2"
Here is the example Get a variable value from the variable name
import java.lang.reflect.Field;
public class Main {
public static void main(String[] args) throws Exception {
Object clazz = new TestClass();
String lookingForValue = "firstValue";
Field field = clazz.getClass().getField(lookingForValue);
Class clazzType = field.getType();
if (clazzType.toString().equals("double"))
System.out.println(field.getDouble(clazz));
else if (clazzType.toString().equals("int"))
System.out.println(field.getInt(clazz));
//System.out.println(field.get(clazz));
}
}
class TestClass {
public double firstValue = 3.14;
}

Related

Command line arguments [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 5 years ago.
I've created a class called Human that works properly, it takes 2 arguments, age and name, to create a human.
To create a Human with command line arguments, I want to write
java Filename -H "Anna" 25
And it should create a Human with thatname="Anna", and thatage=25, where 25 is an int.
The code I've written is creating a list called Argument, and iterating through it to find -H. I need to do this because I'm going to be using this to create different classes later. I just need help with the syntax on the lines where I've written thename=, and theage=, because I don't know how to get the next item in list, and next-next item in list.
public static void main(String[] args) {
ArrayList<String> Argument = new ArrayList<String>();
for (String item: args) {
Argument.add(item);
}
for (String item2: Argument) {
if (item2 == "-H") {
thatname = Argument.get(item2+1)
thatage = Argument.get(item2+2)
Human person = new Human(thatname,thatage);
System.out.println(person);
}
Why not just loop the args?
for ( int i = 0; i < args.length; i++ ) }
if (args[i].equals("-H")) {
i++;
thatName = args[i];
i++;
thatAge = args[i];
}
}
You should add some code to catch if one does not follow the rules you have set. Probably not enough arguments or other things humans do at the keyboard...
thatname = Argument.get(Argument.indexOf(item2)+1);
thatage = Argument.get(Argument.indexOf(item2)+2);
OR you know that 1st element is -H, 2nd element is name and 3rd is age, so you can use below code directly
thatname = Argument.get(1);
thatage = Integer.parseInt(Argument.get(2));
Your code have some problems, let me explain them to you for your assistance.
You cannot compare Strings with == you have to use equals method
in the String to compare between two Strings.
You have to use this for loop for(int i = 0; i < Argument.size();
i++) syntax so that you can iterate from zero to the number of
items in the list.
get method in ArrayList take the index as parameter and return the value at that index.
You can add i += 2 to skip the next two iterations which will
return the name and age value of the human. (It is optional)
Here is the working code:
public static void main(String[] args) {
ArrayList<String> Argument = new ArrayList<String>();
for (String item: args) {
Argument.add(item);
}
String currentItem;
for (int i = 0; i < Argument.size(); i++) { // it will iterate through all items
currentItem = Argument.get(i); // getting the value with index;
if (currentItem.equals("-H")) {
String thatname = Argument.get(i+1);
String thatage = Argument.get(i+2);
i += 2; // Skipping 2 iterations of for loop which have name and age human.
Human person = new Human(thatname,thatage);
System.out.println(person);
}
}
}
You cannot iterate the list using String. When iterating a list you required a index number like list.get(indexNumber);
public static void main(String[] args) {
ArrayList<String> Argument = new ArrayList<String>();
for (String item: args) {
Argument.add(item);
}
for (int i=0;i<args.length;i++) {
if (args[i].trim().equals("-H")) {
i++;
thatname = Argument.get(i);
i++;
thatage = Argument.get(i);
Human person = new Human(thatname,thatage);
System.out.println(person.getName()+" "+person.getAge());
}
Why using array list when you can directly use args? and while you're having only two parameters don't use a for loop access them direclty.
One thing you should know is that String is an object in java so comparing two Strings with == sign will return false even if they have same value (== will compare the id of the object), you should use .equale() function to compare the value of the object.
Check out this code :
public static void main(String[] args) {
if(args.length>0)
{
try{
if (args[0].equals("-H")) {
Human person = new Human( args[1],args[2]);
System.out.println(person);
}
}catch(ArrayIndexOutOfBoundsException exception) {
System.out.println("error with parameters");
}
}else
System.out.println("No command");
}

Array in Method Header: error ']' expected (Java)

I'm quite new to arrays and methods, and I've been seeing this error recurring through several programs: error '[' expected.
In each occasion, it seems to correct itself as I adjust something else, but in this particular case, I am completely stumped.
By the way, I am using several methods and arrays to create a quiz (before you ask, yes, this is an assignment and I agree, a list is a better way to handle this data - but that is not an option).
It is possible that I am not passing the arrays correctly between methods, as I'm a little muddy on that process. From my understanding, in order to send/receive (i.e. import/export) an array or other variable between methods, I must declare that variable/array in the method header parameters.
import java.util.Scanner;
public class H7pseudo
{
public static void main(String[] args)
{
//call getAnswerkey method
getAnswerkey(answerkey[i]);
//call getAnswers method
getAnswers(answers[i]);
//call passed method? necessary or no?
boolean passed = passed(answerkey[i], answers[i], qMissed[i], points);
//Print results of grading
if (passed)
{
System.out.println("Congratulations! You passed.");
}
else
{
System.out.println("Try again, sucka. You FAILED.");
}
//call totalPoints
totalIncorrect(points);
//call questionsMissed
questionsMissed(qMissed[i]);
}
//get answer key (create answerkey array & export)
public static void getAnswerkey(answerkey[i])
{
//create answerkey array here
char[] answerkey;
//determine number of questions (indices)
answerkey = new char[20];
//input values (correct answers) for each index
//for our purposes today, the answer is always 'c'.
for (int i = 0; i <=20; i++)
{
answerkey[i] = 'c';
}
}
//get student answers (create answers array & export)
public static void getAnswers(answers[i])
{
//initialize scanner for user input
Scanner scan = new Scanner(System.in);
//create answer array here
char[] answers;
//determine number of questions (indices)
answers = new char[20];
//prompt for user input as values of each index
for (int i = 0; i <= 20; i++) {
answers[i] = scan.nextChar();
}
}
//grade student answers (import & compare index values of arrays:answers&answerkey
//create & export qMissed array
public static boolean passed(answerkey[i], answers[i], qMissed[i], points)
{
int points = 0;
//create new array: qMissed
boolean[] qMissed;
//determine number of questions to be graded
qMissed = new boolean[20];
//initialize values for array
for (int i = 0; i <= 20; i++) {
qMissed[i] = false;
}
//cycle through indices of answerkey[i] & answers[i];
for (int i = 0; i =< 20; i++)
{
if (answers[i] == answerkey[i])
{
correct = true;
points = points+1;
qMissed[i] = true;
}
else {
qMissed[i] = false;
}
}
//evaluate whether or not the student passed (15+ correct answers)
if (points >= 15)
{
passed = true;
}
else
{
passed = false;
}
return passed;
}
public static void totalIncorrect(points)
{
int missed = 20 - points;
System.out.println("You missed " + missed + " questions.");
}
public static void questionsMissed(qMissed[i])
{
// for each index of the array qMissed...
for (int i = 0; i < qMissed.length; i++)
{
//...print correct and false answers.
system.out.println(i + ": " + qMissed[i] + "\n");
}
}
}
You can't define array size in the method signature, in Java.
public static void getAnswerkey(answerkey[i])
You can't put anything inside the [] in a method declaration. Also, you have to mention the type:
public static void getAnswerKey(char[] answerkey)
This is not the only reason your code won't work as intended, but I'll leave the rest as part of the exercise.
Look at your method definitions:
public static void questionsMissed(qMissed[i])
This is wrong. You should define the type of the variable and it should not contain [i] like an element of an array. It should be something like this:
public static void questionsMissed(int qMissed)
Or if you want to pass the array, write it like this:
public static void questionsMissed(int[] qMissed)
Apart of this, there are other several errors in your code:
getAnswerkey(answerkey[i]); //answerkey is not defined
getAnswers(answers[i]); //answers is not defined
It would be better if you start reading a Java tutorial first.
I want to vote up Luiggi's answer, but I don't have enough reputation to do that :)
Congrats, cordivia, on getting started with Java!
Here is how an array is declared:
type[] arrayName = new type[numberOfElements]
For example, you did this right in your method definition for getAnswerkey():
char[] answerkey;
answerkey = new char[20];
The part in the method definition inside the parentheses defines the kind of data the method is willing to accept from the outside. So if you don't need to put something into the method to get something out of it, you don't need to put anything in the parentheses. Define the method like this:
getAnswerkey() {
...But that's not the whole story. If you want to get something out of the method, it needs to have a return type as well. A return type is what you're gonna get out of the method when the method's done doing it's magic. For example, if you want to get an int array out of a method you would do something like this:
public static int getTheInteger() {
Since you want an array of chars from the method, you'll want to do something like this:
public static char[] getAnswerkey() {
So that's how you get a method to give you something back. If don't want anything back, you put void:
public static void noMarshmallows() {
Now, when you use the method, you're gonna need to do something with what it gives you, or it did all that work for nothing. So you need to store the return value in a variable when you call the array (calling methods is what you've been doing in main). You know how to store something in a variable. You use the '=' operator:
int myVeryFavoriteNumber;
myVeryFavoriteNumber = 5;
So, you do the same thing when you're getting something out of an array. You assign the return value to a variable. If you want to do this with an array, do this:
int[] myFavs;
myFavs = getMyFavoriteNumbers();
Same with chars:
char[] answerKey;
answerKey = getAnswerKey();
Voila! Your answer key is now right out in the open for the rest of main to see :)
Now, if you want to put something into a method and have it do something with what you put in, you define a parameter. You know how this works. It's just like declaring a variable, and that's exactly what it is. Parameters go in the parentheses and only the method using the parameter sees that variable name (it's local). Something like this:
public static void plusOneToAll (int[] numbers) {
for (int i = 0; i < numbers.length; i++) {
numbers[i] = numbers[i] + 1;
}
}
Notice int[] numbers in the parentheses. The type being passed in is int[] or integer array. numbers is just the parameter name. It functions just like a variable, but it is declared locally (inside the parentheses) and use locally (inside the method). So, if you wanted to compare the answers from two arrays and return the number of matches (like a total score for instance), you would do something like this:
public static int getTotalScore (char[] correctAnswers, char[] userAnswers) {
int totalScore = 0;
for (int i = 0; i < correctAnswers.length; i++) {
if (userAnswers[i] == correctAnswers[i]) {
totalScore = totalScore + 1;
}
}
return totalScore;
}
Notice the return type: int (written before the method name). Inside the array I'm using the variable totalScore to keep track of the number of times the answers match. The method takes two char arrays from the outside and uses them on the inside. Finally, I return an int: totalScore. That kicks the value of totalScore back out to whatever called it (main).
If I might add one last thing: Do yourself a favor and go pick up a copy of Head First Java. It's hard to find a good tutorial online and Java textbooks are just plain boring. The Head First series are kind of like coloring books for adults.
Best of luck!

need to store value after passing to method for latter check

I am passing few values to mail method for sending the details like below
private static String getTeam(String Team, List<String> prioritys1, String number,String description
) {
StringBuilder builder1 = new StringBuilder();
for (String v : prioritys1) {
if ( v == "1") {
Integer cnt1 = count1.get(new Team(Team, v,number,description));
if (cnt1 == null) {
cnt1 = 0;
}
else
if (cnt1 !=0){
cnt1 = 1;
mail1(Team,v,number,description);
}}
else
if ( v == "3") {
Integer cnt1 = count1.get(new Team(Team, v,number,description));
if (cnt1 == null) {
cnt1 = 0;
}
else
if (cnt1 !=0){
cnt1 = 1;
mail1(Team,v,number,description);
}}
}
return builder1.toString();
}
I tried to store in arrays but it didnt worked.
I after pass above parameters, i need to store the value of the number. i need to store the number so that next time while passing the parameters i need to check first whether the number is already passed or not if not then only i need to pass to mail.
can any one help on this
With this code very complicated understand what you are doing. But if you need check value that already been processed store it outside of the method. Create global class variable:
public class className {
private final List<String> ARRAY = new ArrayList<>(); // global variable
public void yourMethod(String value) {
if (!ARRAY.contains(value)) {
mail(value);
ARRAY.add(value);
}
}
}
I dont know your case and I can not get better example.
You need to store the value in a "class level" variable. Whether the variable type needs to be static or instance will depend on your implementation of the method.
If you can post a sample code, we can help further.
You need to compare with 2 equals and not 1
Instead of
if( Team = A )
you need this way
if( Team == A )
Using Team = A, your saying that every time your code reaches that line it will equal Team to A.

java : mapping the Values from Enumeration to Object

I have a Enumeration as shown in below program
public class Test {
public static void main(String args[]) {
Vector v = new Vector();
v.add("Three");
v.add("Four");
v.add("One");
v.add("Two");
Enumeration e = v.elements();
load(e) ; // **Passing the Enumeration .**
}
}
There is also a Student Object
public Student
{
String one ;
String two ;
String three ;
String four ;
}
i need to pass this Enumeration to another method as shown below
private Data load(Enumeration rs)
{
Student stud = new Student();
while(rs.hasMoreElements())
{
// Is it possible to set the Values for the Student Object with appropiate values I mean as shown below
stud.one = One Value of Vector here
stud.two = Two Value of Vector here
stud.three = Three Value of Vector here
stud.four = Four Value of Vector here
}
}
Please share your ideas on this .
Thanks
Sure. You could use the elementAt method, documented here, to get the value you wanted. Do you have a specific reason you are using a Vector? Some of the List implementations might be better.
Enumerations don't have the idea of "first value", "second value", etc. They just have the current value. You could work around this in various ways:
The easy way -- convert it to something easier to work with, like to a List.
List<String> inputs = Collections.list(rs);
stud.one = inputs.get(0);
stud.two = inputs.get(1);
// etc.
Keep track of the position yourself.
for(int i = 0; i <= 4 && rs.hasNext(); ++i) {
// Could use a switch statement here
if(i == 0) {
stud.one = rs.nextElement();
} else if(i == 1) {
stud.two = rs.nextElement();
} else {
// etc.
}
}
I really don't recommend either of these things, for the following reasons:
If you want your parameters in a particular order, just pass them in that way. It's much easier and it's also easier to maintain (and for other people to read).
void example(String one, String two, String three, String four) {
Student student = new Student();
student.one = one;
student.two = two;
// etc.
}
You shouldn't use Enumeration at all, since it's been replaced with Iterator and Iterable since Java 1.2. See ArrayList and Collection.

Why am I getting an "xxx is already defined" compiler error?

I am trying to create multiple threads using variable like threadname1, threadname2,..threadnamen. Instead of giving it as a hard coded value I am trying to do it using a for loop for the n numbers and use that at the end of "threadname" string. It throws some error. How do I fix this issue?
public class RunnableExample{
public static void main(String[] args){
String Name = "";
String Ip = "";
for (int i=1; i<=2; i++){
if(i == 1){
Name = "irony";
Ip = "82.209.27.24";
}
else{
Name = "jocky";
Ip = "98.12.098.56";
}
String runname = "threadname" + i;
RunnableThread runname = new RunnableThread(Name,Ip);
new Thread(runname).start();
}
//RunnableThread threadname1 = new RunnableThread("irony","82.209.27.24");
//RunnableThread thread4 = new RunnableThread("jocky","98.12.098.56");
//new Thread(threadname1).start();
//new Thread(threadname2).start();
try{
}
catch (InterruptedException e) {
}
}
Output:
bash-3.00# javac RunnableExample.java
RunnableExample.java:43: runname is already defined in main(java.lang.String[])
RunnableThread runname = new RunnableThread(Name,Ip);
How do I resolve this issue? Maybe some typecasting is required it seems. I am not sure.
This is your problem:
String runname = "threadname" + i;
RunnableThread runname = new RunnableThread(Name,Ip);
You're trying to declare two variables with the same name. You can't do that. Change the name of one of the variables. The names of variables are fixed at compile-time in Java. You can't say "declare a variable with the name of the execution-time value of this variable" which is what I think you're trying to do.
If you want a way of accessing multiple values, use a collection or an array. For example, you might want a List<RunnableThread> here - add the value to the list in each iteration of your loop.
I'd also strongly recommend that you make sure you understand the basics of Java (things like variables and collections) before you start try experiment with threading. Threading is complicated and can be very hard to reason about - it's going to be even harder if you're struggling with the core language.
Probably a typo, you wanted to type :
String Name = "threadname" + i;
RunnableThread runname = new RunnableThread(Name,Ip);
You have to change the name of your variable containing the thread name :
String threadName = "threadname" + i;
RunnableThread runname = new RunnableThread(threadName, ip);
A good thing to do if you work with Java is to use the Java naming convention. For example all variable start with a lower case.
You might have wanted to do this :
import java.util.HashMap;
import java.util.Map;
public class RunnableExample {
public static void main(String[] args) {
Map<String, RunnableThread> threadMap = new HashMap<String, RunnableThread>();
String name = "";
String ip = "";
for (int i = 1; i <= 2; i++) {
if (i == 1) {
name = "irony";
ip = "82.209.27.24";
} else {
name = "jocky";
ip = "98.12.098.56";
}
String threadName = "threadname" + i;
RunnableThread thread = new RunnableThread(name, ip);
new Thread(thread).start();
threadMap.put(threadName, thread);
}
threadMap.get("threadname1").getIp();
}
}
Resources :
Oracle.com - Naming Conventions
I won't bother pointing out the problem of your posted code because others already have. I will however suggest you do not use a for loop if you are going to be doing if checks inside it to see which iteration you are on. This is not a good practice. Infact, a non iterative solution is actually less lines of code and cleaner...
Thread ironyThread = new RunnableThread("irony", "82.209.27.24");
Thread jockyThread = new RunnableThread("jocky", "98.12.098.56");
ironyThread.start();
jockyThread.start();
Something like that will do what you are trying. I know you said that you want it to handle N threads. My solution would still be cleaner that the pattern you are following; adding an if check around each iteration for different threadName values.

Categories