Java - What is this asking me to do? - java

It's as follows:
I highlighted the part that I don't understand. What exactly does it mean when it's asking me to make those methods accept only two parameters? It seems like you would need 3, which are the test scores for each respective test?
The code I have so far:
public class Student {
private String ID;
private double test1;
private double test2;
private double test3;
private double average;
public Student(String sID, double sTest1, double sTest2, double sTest3, double sAverage)
{
ID = sID;
test1 = sTest1;
test2 = sTest2;
test3 = sTest3;
average = sAverage;
}
public Student(String sID)
{
ID = sID;
}
public void setTestScore(double sTest1, double sTest2, double sTest3)
{
}
public void getTestScore(double sTest1, double sTest2, double sTest3)
{
}
public double calcAverage()
{
average = (test1 + test2 + test3) / 3;
return average;
}
public void displayInfo(String ID, double test1, double test2, double test3, double average)
{
System.out.println("Student ID: " + ID);
System.out.println("Test 1 Score: " + test1);
System.out.println("Test 2 Score: " + test2);
System.out.println("Test 3 Score: " + test3);
System.out.println("Average test score: " + average);
}
}
Any insight as to what it's expecting me to do with the getTestScore and setTestScore methods would be appreciated.
Edit: Looks like the solution is to just use an array to store the values? I thought that would defeat the purpose of structuring it this way but it seems like as a beginner my options are a bit limited.

What exactly does it mean when it's asking me to make those methods accept only two parameters? It seems like you would need 3, which are the test scores for each respective test?
That would be one way to do it, but they want to do it slightly differently.
They want to have a method that sets the score only for a single test.
That is probably better as it
can be adapted easily to a greater number of tests
allows to set the scores one-by-one (as you may not even know the other scores yet).
So the "extra" parameter specifies which test you are talking about here.
To set all three scores, you would call this method three times (with different parameters).

Setter should have 2 parameters: test number and score
public void setTestScore(int testNo, double score) {
//YOUR HOMEWORK
}
Getter should return the score for the test number
public double getTestScore(int testNo) {
return YOUR_HOMEWORK;
}
Your Assignment in this case is to think of a good data structure to hold the results of a number of tests (currently three) and to retrieve them at a later time.
Hint: as others here have already suggested, you might think of a datastructure to map key values (your test number) to values (your score). The most basic of these structures being an array where the index is your key (watch out: zero-based!) and score is the value at that index...
With Arrays
You could still have some way of initialization to specify how many tests there are to be. Lets for a moment think of double[] scores = new double[3]; as a member variable in your class. Setting the 3rd test to score would be as simple as scores[2] = score;. Getting the result of the first test simply is scores[0];

The set method shouldn't accept all 3 scores at once. It should accept a single score parameter and a second parameter (int whose value is between 1 to 3) to indicate which test score should be updated.
Similarly the get method should accept the test number (between 1 and 3) and return the corresponding score.

The first method should add a test and a score to a Collection, let's say a HashMap<Integer, Double>. Like this:
public void addScore(int testId, double score) {
myTestsMap.put(testId, score);
}
The second part should retrieve the score from the map, like this:
public double getScoreForTest(int testId) {
if(myTestsMap.containsKey(testId){
return myTestsMap.get(testId);
} else {
return -1;
}
}
myTestsMap should be a class field so it's state is kept. Create it in the constructor like that:
myTestsMap = new HashMap<Integer, Double>;
As for a theoretical background:
the two methods are so-called getter and setter. It is a good practice to keep your class fields private and only allow access through such methods. It allows you to analyze the in-coming and out-going data, among other things.
Map is a data structure which maps a set of unique keys to non-unique values. HashMap is one of Map's implementations.

Another option not mentioned here is to hold your test scores in an ArrayList:
public class Student {
private String ID;
private ArrayList<Double> testScores = new ArrayList<>();
//CONSTRUCTOR
public void setTestScore(int testNumber, double score) {
//YOUR HOMEWORK
}
public double getTestScore(int testNumber) {
//YOUR HOMEWORK
}
Now you can add your test scores and they can be positional based on the index in the list. Note that ArrayList is also 0-based, so you'll have to correct for that. This approach also gives you the added benefit of being able iterate through test scores and print them out in the correct order.

The student object should have a Map<Integer, Double> field that stores the test number as the key and the score they got on that test as the value. The set method will put(testNumber, score) and the get method will return the test score by get(testNumber);
What seems confusing perhaps is the requirement to provide a constructor that sets all fields? Perhaps you expect the constructor method signature to look just like the setTestScore method?
If you're still in need of help, try to think a second about what the lesson is about. Are you learning about collections?

What exactly does it mean when it's asking me to make those methods accept only two parameters? It seems like you would need 3, which are the test scores for each respective test?
Try thinking about what the method is supposed to do, rather than how you would go about doing it.
The name of the method is a giveaway - setTestScore.
That would indicate to me, that I want to set the score for a single test.
Now, I would ask myself, what information would I need to change the score for a single test?
I would need something that identifies an individual test. E.g the integer 0 for test 1, integer 1 for test 2 etc.
I would also need the actual test score, so that I can store it.
Now I know that I likely need two parameters, one for the test identifier, and one for the test score.
So now, I need a way to store the test score in a specific place using the identifier.
Given that I have an identifier which is an integer, it should hopefully be clear that I would want to use an array.
The reason I would choose an array is because it accepts an integer, and allows me to access the data at that place in the array.
A section of pseudocode to highlight what I have proposed above:
setTestScore ( parameter1 testIdentifier, parameter2 testScore )
ArrayOfTestScores[testIdentifier] = testScore
Note regarding your second question
It seems like you would need 3, which are the test scores for each
respective test?
If someone sent you the following information in an email,
and asked you to store/update the value for a student's test in an excel sheet:
no value
65.7
no value
Sure, you can see right away you need to update the student's second test.
But, is there a better way?
How about the person just sends me the test number and the score?
Test 2: 65.7
Seems to be easier, because I have an actual identifier for the test to be updated.
And I also don't need redundant information in the email.
When starting off with programming it can help to try and turn the problem into a real life example which you can hopefully relate to. It could help you understand what makes sense and what doesn't. Eventually, as problems get trickier, you will likely need to learn some formal approaches to problem solving. But for this example, making a simple real life equivalent of what you're doing can help.

Ideally you would want to have everything object oriented, that would mean that the Test themselves would be their own class.
I think what is expected is that the first value is the number of the test (1 through 3) and the second value is the actual value. So the method signature that you have is wrong. It should just have two paramters. The first being the number and the second being the score.
What happens after the setter is called?
Well... you have to decide on some structure to store that data. It is basically three pairs of data. Like I mentioned before, it would be nice to have a Test class, but a simple data structure should suffice. I will give you a hint about the data structure : it should be key/value based. The key is the id of the Test, and the value is the value of the test. Have a read about java collections to see if there is any kind of data structure that can help you with this.

I think you are supposed to create a Map of some kind, with the test ID as a key, and the score as a value.
Your setter would populate the map with the score for the current test ID.
Your getter would retrieve the score in the map, corresponding to the asked test ID.

What exactly does it mean when it's asking me to make those methods
accept only two parameters? It seems like you would need 3, which are
the test scores for each respective test?
the method should accept test-id and test-score, and set data to proper attribute,
public void setTestScore(int testNumber, double testScore)
{
if(testNumber == 1)
test1=testScore;
else if(testNumber == 2)
test2=testScore;
else if(testNumber == 3)
test3=testScore;
}
and get method should take 1 param (testNumber)
public double getTestScore(int testNumber){
if(testNumber == 1)
return test1;
else if(testNumber == 2)
return test2;
else if(testNumber == 3)
return test3;
}

Related

int vs Integer vs a user made class to achieve effective pass by reference behavior in Java

Let's say you have a class of object with three
integer fields that you want to possibly change, all in the same way, with one method.
Let's keep it simple and say all that the method does is add 1 to the parameter passed to it.
That is to say, the desired behavior is that by the time the method has completed, the relevant field has increased by 1.
This is impossible to achieve in Java using the primitive type "int" for those fields.
I know about how Java is "always" pass by value, and not pass by reference,
- and - i've heard whisperings on the internet that this is one reason that the Integer class exists, along with other object "wrapper" classes
for ordinarily primitive types such as int and double.
Sending an object as an argument to a method should, in theory, provide a way to [effectively, if not technically] pass by reference, since the value that is passed, is supposedly the value of the reference to the object.
Very tricky. BUT - and this is where my annoyance comes in - I've tried achieving this very simple task by passing an Integer argument instead of an
int, and the desired behavior was still not accomplished. 1 was not added to the relevant field.
And yet, when I made my very own object, which consisted of just one field, an int value, and passed an instance of this object as an argument
to an appropriate method which would simply add 1 to the passed parameter, the desired behavior was in fact accomplished. 1 was added to the relevant field.
So the questions orbiting around this query are - Is it really going to be necessary to craft my own homemade class just to carry a simple integer value
every time I want to achieve this desired behavior? Can the existing tool provided by Java, Integer, really not perform this simple task?
Instead of having one nice, neat method to handle all three of the hypothetical integer fields i mentioned in the beginning, I felt compelled (in a separate, similar project that ultimately provoked this line of thinking) to make a separate method corresponding to each of the three fields, with essentially the same exact code in each one. This seems very inefficient.
It may not seem like a big deal, on the surface, to write three similar methods instead of one, but to clarify why this dismays me - imagine instead of an object with three integer fields as I stated, there are say, i don't know, four thousand. It would be so much better to write just one thing to perform the same kind of behavior, instead of copying and pasting (and changing whatever little bits necessary) four thousand times.
So I suppose the ultimate question is,
Why doesn't Integer function in a reasonable way? What's the point of wrapping a primitive in an Object at all, if it doesn't even help perform something this simple? Am I missing something simple about how to get Integer to function in the desired way? (Hopefully so) The answer seems close yet infuriatingly out of reach since "RInteger" produces the desired behavior, yet "Integer" doesn't.
The entire source code I used while trying to figure out how to construct this painstaking question is below.
package r9mp;
import javax.swing.SwingUtilities;
public class RefTest2 {
//[main m]
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable(){
public void run(){
new RefTest2();
}
});
}
//[fields]
int i;
Integer I;
RInteger RI;
//[constr]
public RefTest2(){
intTest();
IntegerTest();
RIntegerTest();
display();
}
//[methods]
private void intTest(){
i = 100;
intMethod(i);
}
private void IntegerTest(){
I = 100; //boxing? auto?
IntegerMethod(I);
I = 100; //just in case.
IntegerMethod2(I);
}
private void RIntegerTest(){
RI = new RInteger(100);
RIntegerMethod(RI);
}
private void intMethod(int ipar){
ipar = ipar + 1;//no change. expected.
}
private void IntegerMethod(Integer IPar){
IPar = IPar + 1;//no change. frustrating.
pln("From inside IntegerMethod: IPar = " + IPar );
pln("From inside IntegerMethod: I = " + I );
}
private void IntegerMethod2(Integer IPar){
IPar = new Integer(IPar+1);//still no change. there are no set methods for Integer, or I'd try them.
}
private void RIntegerMethod(RInteger riPar){
riPar.value = riPar.value + 1;
}
private void display(){
pln(
"Display... \n" +
"i: " + i + "\n" +
"I: " + I + "\n" +
"RI: " + RI + "\n" +
"--------"
);
}
private void pln(){
pln("");
}
private void pln(String s){
System.out.println(s);
}
//[internal class]
private class RInteger{
int value;
public RInteger(int v){
value = v;
}
public String toString(){
return ""+value;
}
}
}
And, here is the output...
How about one method for primitives and their wrappers?
private int incInteger(int value)
{
return value + 1;
}
and call for it:
int intVal = 100;
intVal = incInteger(intVal);
Integer integerVal = 200;
integerVal = incInteger(integerVal);
First of all, you need to read up on immutability to find out why it is a very good thing to have. There even exist entire languages (functional, mostly) that capitalize on it.
Once you have read about that, then read Eric Lippert's series of articles on immutability. Start here: https://blogs.msdn.microsoft.com/ericlippert/2007/11/13/immutability-in-c-part-one-kinds-of-immutability/ Mind = blown.
But to give you a quick hint as to why primitive wrappers like Integer are immutable, let me just say that these classes are often used as keys in Hash Maps, and a key must be immutable, so that its hashCode will never change, otherwise the hash map will fail with very difficult to track down behaviour. Mutable keys in hashmaps are nasty bugs.
You can achieve what you want with a class of your own devise which plays the role of a reference, or by simply passing an array and modifying the element at array[0].
My personal preferences are as follows:
I would try to do as much as possible with return values.
When return values are inapplicable, (as the case is with invokeLater,) then inner/nested/anonymous classes that have access to the fields of the enclosing class are my next preference.
When that's not an option either, then special classes crafted precisely for the application at hand are my next option. (MyMutableNumberWrapper.)
And when I just want something quick and dirty, then general-purpose classes like Ref<T> (or even single-element arrays) would be my final option.

Organize similar functions in a class

I have a method that gets a matrix of 11xm values (m is variable), analyzes the data and returns an array of features based on that matrix.
I've already written a long function to process this data, however, I wanted to convert it to a class since I will need to extend it later.
My issue is related to how I should organize some functions.
I thought about having a "get" function for each feature extracted from the raw data.
the problem is that different functions will need the same exact preliminary calculations.
For example, I have many x&y points, and I will first need to calculate the pairwise distances, then velocities, then accelerations, and angles. Then all this data will be used to calculate some features.
For example, in the following, if I need to call preliminary1 for both feature 1 & 2, that's twice the work, and I might actually need the same preliminary calculations for 4 or 5 subsequent features (functions). I might need some more calculations for feature 3 that would also need preliminary 1.
Any ideas on how to do this?
private double[] preliminary1(double[], double[]) { some calculations}
private double[] preliminary2(double[]) {
value = preliminary1(value1, value2);
// more calcuations }
public double getFeature1() {
value = preliminary1(value1, value2);
// more calcuations }
public double getFeature2() {
value = preliminary1(value1, value2);
// more calcuations }
public double getFeature3() {
value = preliminary2(value1);
// more calcuations }

Return two Strings from method

I'm a beginner in Java programming, and I'm trying to make a voting machine program, where you can vote for Republicans or Democrats. My question is, how can I edit my method so I would be able to return two strings with two distinct values?
For example, look at my code all the way in the bottom. It's wrong, but I wanted the tester to be able to print out Democrats: (some number) and Republicans: (some number) in one method. How can I do that?
import java.lang.String;
public class VotingMachine1 {
private double Democrats;
private double Republicans;
public VotingMachine1() {
Democrats = 0;
Republicans = 0;
}
public void voteRepublican() {
Republicans = Republicans + 1;
}
public void voteDemocrat() {
Democrats = Democrats + 1;
}
public void clearMachineState() {
Republicans = 0;
Democrats = 0;
}
//this is where I'm having difficulties. I know its wrong
public double getTallies() {
System.out.println("Democrats: ", return Democrats);
System.out.println("Republicans: ", return Republicans);
}
}
No return is necessary there, since you aren't leaving a function. To do what you seem to want to do, just replace that last method with the following:
public void getTallies()
{
System.out.println("Democrats: " + Double.toString(Democrats));
System.out.println("Republicans: " + Double.toString(Republicans));
}
Also, since your votecounts should only ever be integers, there's no reason to declare them as doubles instead of ints.
What you are looking for here is a format string. A format string is used when you know what your output should look like, and only have a few "holes" where unknown data should be filled in. To output your data using format strings, you would use the System.out.format(String, Object...) method:
System.out.format("Democrats: %f\n", Democrats);
System.out.format("Republicans: %f\n", Republicans);
In this case, the %f indicates that a floating-point number (since your variables are declared as double) will be printed instead of the %f. However, you may wish to consider declaring them as int (or long) instead, in which case you would use %d instead of %f in the format strings.
Finally, you ought to change your getTallies() method to return void instead of double, as you are printing the values, not returning them.
Your code and your description are so contradictory, it is not clear that you even know what you are trying to do. I believe that this is the real root of your problems.
Here goes:
public double getTallies()
{
System.out.println("Democrats: ", return Democrats);
System.out.println("Republicans: ", return Republicans);
}
First, your question says that you want to "return two strings with two values" ... but you have declared the method as returning one double.
Next, your code is printing values ... not returning them.
You've also made some major mistakes at the syntactic level, largely (I believe) because you are trying to do contradictory things:
return Republicans is not a valid Java expression, so you can't use it as a argument to the println method.
The println method can't be called with two arguments, as your code is trying to do. There is a zero argument version and a number of one argument overloads ... but no overloads with two or more arguments.
Basically, you need to start by making up your mind about what this method is supposed to do. Is it supposed to:
return the tallies (as two doubles)?
return a string representing the two tallies?
return nothing ... and output the two tallies to standard output?
do something else?
Once you've made up your mind:
code the method to do what you've decided it should do, and
chose a method name that correctly reflects what it is supposed to do. Hint: a method that starts with get is conventionally a "getter" that returns the attribute or attributes themselves ... not a String rendering.
double is a bad choice of type for a vote count too:
You cannot have a fractional vote.
You want to represent vote counts precisely and floating point types (like double) are not precise. (Or at least, not in the sense that you require.)
When you attempt to format or output a double, the resulting character string is likely to include a pesky decimal point ... or worse.
You should use int or long instead of double.
Finally, this is a serious Java style violation, and should get you a significant penalty if your marker is paying attention.
private double Democrats;
private double Republicans;
Variable names in Java should start with a LOWER CASE letter.
A few more random comments:
import java.lang.String; is superfluous as all classes in package java.lang are automatically imported in every Java source file.
Votes can not be fractional. People can't vote 0.75 candidate A, and 0.25 candidate B. If you use integer datatypes (int or long), you will be reflecting this fact better. Also, you will be saving yourself a lot of headache when you start obtaining results like 379857.999999. This is because floating point types have a better range, but worse precision (especially noticeable when working with pure integers).
According to Java usual naming conventions, variable names should start with a lowecase letter.
A better name for function getTallies is printTallies.
For output purposes, it's much better to use string formatting than concatenation. Some advantages are: multiple formats supported, ease of use, and internationalization.
Putting all together:
private int democratVotes;
private int republicanVotes;
public void printTallies() {
System.out.format("Democrats: %,d%n",democratVotes);
System.out.format("Republicans: %,d%n",republicanVotes);
}
In this particular case, votes will be printed with thousand separation (ex: 3,345,623 instead of 3345623). Check Java's Formatting Numeric Print Output tutorial.
Thinking better about it, there are some alternatives where getTallies would effectively be returning some form of value:
1) Make it to return a String with both tallies. It would be hard and inefficient to separate the tallies later, though.
public String getTallies() {
return "Democrats: %,d votes. Republicans: %,d votes.%n".format(democratVotes,republicanVotes);
}
2) Make it to return an array.
public int[] getTallies() {
return new int[2]{ democratVotes, republicanVotes };
}
public int[] getTallies1() { // Same as getTallies, but written step by step.
int[] result= new int[2] ;
result[0]= democratVotes ;
result[1]= republicanVotes ;
return result ;
}
3) Make it to return a class.
public VotingMachineResults getTallies() {
return VotingMachineResults(democratVotes,republicanVotes) ;
}
public static class VotingMachineResults {
private int democratVotes;
private int republicanVotes;
public VotingMachineResults(democratVotes,republicanVotes) {
this.democratVotes= democratVotes ; // `this` required to disambiguate field democratVotes from parameter democratVotes.
this.republicanVotes= republicanVotes ;
}
public int getDemocratVotes() {
return democratVotes ;
}
public int getRepublicanVotes() {
return republicanVotes ;
}
}
As you can see, this class is very similar to VotingMachine1, but it does not accept internal state changes. It is a "value" class.
In Java, you concatenate Strings with the + operator. Proper syntax for what you were trying to do looks like this:
System.out.println("Democrats: " + Democrats);
System.out.println("Republicans: " + Republicans);
A return statement is only used when you want to return some object or value to a method that called your current method. It is not appropriate in this place since you're only passing a value to another method (println()).
ALSO, you need to fix your getTallies() method. Make it return void instead of double since you aren't returning anything.
Here's something completely different: why not override toString()?
Presumably, any instance of VotingMachine1 will apply for all votes that you care about for that instance. That is to say, you don't create a new instance of a VotingMachine1 every time someone casts a vote.
So, what you can do is override the toString() method. We'll also use String.format() to handle the numerical values.
#Override
public String toString() {
// assumes that Democrats and Republicans are declared as int
// since it's pointless to indicate percentages of a vote
return String.format("Democrats: %d\nRepublicans: %d", Democrats, Republicans);
}
Now, whenever you vote, you can use the toString() method to get the information (which is called whenever one does System.out.println(object).
VotingMachine1 voter = new VotingMachine1();
voter.voteDemocrat();
voter.voteRepublican();
System.out.println(voter);
/* This prints:
Democrats: 1
Republicans: 1
*/
A less specific answer to your question would be to return an Object called (say) Votes
public class Vote {
int democratVotes
int republicanVotes
}
and then make your VotingMachine class simply return an instance of this object (suitably changed to make it immutable).
On my project we have created a generic version of this called a Tuple that returns a pair of values in a single object - it has an overloaded toString method for easy printing.
you can return an array with [0] and [1] as key and devide it on the basis of your need..
like
returnArray[0]="first string";
returnArray[1]="second string";
and use it ur way...

sending value to another method in another class in JAVA

sorry I'm new to java. I want to pass the mark1 to class Exam in method Calculator, but I got some error how can i do that the program say incompatibe type. What can I do?
I want to send mark1 from this method:
public float SendMark(){
Exam ex = new Exam();
for (int i=0; i<students.length; i++) {
mark1 = students[i].getMark();
}
return ex.Calculator(mark1);
}
to this class and method calculator ... but it say incompatible type ... to this method i want to sum the Array value and get average of the array values ... is it correct way ?? what should i write here ...? please help me details thanks ...
public class Exam {
public Calculator (float mark1) {
AddList ad = new AddList();
}
}
you are missing the return type for the method calculator.
public Calculator (float mark1)
should be
public float Calculator (float mark1)
Your Calculator method does not have a return statement and its signature (the method header) does not declare a return type.
Also, I can't see where you declared mark1, you only initialized it in the for loop.
Meanwhile, I also spotted a logic error, the mark1 will always send the last score in the array because its value would be repeatedly overwritten in the loop; only the last value survives.
When you do not need return type, you type void method_name(args), like in C. Void is the placeholder for no return type. Secondly, your code is better than of other noobs, but you still have a lot of unnecessary details, which means that you did not debug yourself. Localize the problem better (remove everything unnecessary to reproduce). It will be simpler then for experts to see your problem immediately. You will even see or guess it yourself. Otherwise, without learning localizing the bugs, you will never become a programmer. And garbage the SO unnecessarily.
there are several small problems in your codes:
usually method name should start with lower letter in java code convention
what does the for loop in SendMark method do? just overwrite a float variable many times?
in your comment, you mentioned you want Exam.Calculator method print result, but no return value. Then you should add void as return type to method Calculator().
if you don't expect any return value from Calculator() method, why you return ex.Calculator(mark1) in your SendMark() method, and type is float?
From what I have understood from your question, here is my answer.
public float **s**endMark(){
Exam ex = new Exam();
for (int i=0; i<students.length; i++) {
mark1 = students[i].getMark(); //this does not make any sense.
}
//Since you insisted that you wanted to only print, just call the calculator method and do not return anything. change the return type of calculator method to void.
ex.Calculator(mark1);
return "something";//since your method's definition says so
}
public class Exam {
public void **c**alculator (float mark1) {
//Do your stuff
}
}
You may also want to look into sun java's coding conventions.
one of the approach is to pass your students array to calculator and inside calclator method iterate over student sum up marks like
marks = marks + students[i].getMark() and avg = marks/students.length
other could be, form marks i your main method by marks = marks + students[i].getMark() and then pass marks and length to calculator method to calculate average.
Also please go through java coding conventions and how to pick return types.
hope this helps.

Can I print out the name of the variable?

I have created a no. of constant variables, more than 1000, those constants are unique integer.
public static final FOO 335343
public static final BAR 234234
public static final BEZ 122424
....
....
....
Is there a way to print out the FOO, BAR and BEZ, the variable of the names in Java?
I am not familiar with java reflection. I don't know if that helps.
if ( FOO == 335343)
---> output "FOO"
if ( BAR == 234234 )
---> ouptut "BAR"
....
Actually asking this question behind is that I want to write log into the file
say
System.out.println("This time the output is " + FOO);
and the actual output is
This time the output is 335323
I want to know which variable comes from 335323.
Is there any other way apart from putting those variable and its associate constant into hashMap?
Thanks
There are some 'special case' that u can have workaround for this (which is told by other), but the most important question is: why would you want to do this (printing out variable name)?
From my experience, 99.9% of similar questions (how to print variable name? how to get variable depends on user inputting variable name? etc) is in fact raised by beginner of programming and they simply have made incorrect assumptions and designs. The goal they are trying to achieve normally can be done by more appropriate design.
Edit
Honestly I still do not think what you are trying to do is the way to go, but at least I think the following is a workable answer:
It is more or less a combination of previous answer:
(Haven't try to compile but at least it give u an idea)
class Constants {
public static final int FOO = 123;
public static final int BAR = 456;
private static Map<Integer, String> constantNames = null;
public static String getConstantName(int constVal) {
if (constantNames == null) {
Map<Integer, String> cNames = new HashMap<Integer, String>()
for (Field field : MyClass.class.getDeclaredFields()){
if ((field.getModifiers() & (Modifier.FINAL | Modifier.STATIC)) != 0) {
&& int.class == field.getType()){
// only record final static int fields
cNames.put((Integer)field.get(null), field.getName());
}
}
constNames = cNames;
}
return constantNames.get(constVal);
}
}
assuming you want to get a constant name, just do:
Constants.getConstantName(123); // return "FOO"
As I noted in my comment to the original post, I have a strong suspicion that the best solution for your current problem is to solve it in a completely different way. You seem to want to associate an int with a String, and one way to do this is to use a Map such as a HashMap. For e.g.,
import java.util.HashMap;
import java.util.Map;
public class MapDemo {
public static void main(String[] args) {
Map<Integer, String> myMap = new HashMap<Integer, String>();
myMap.put(335343, "FOO");
myMap.put(234234, "BAR");
myMap.put(122424, "BEZ");
int[] tests = {335343, 234234, 122424, 101010};
for (int i : tests) {
// note that null is returned if the key isn't in the map
System.out.printf("%d corresponds to %s%n", i, myMap.get(i));
}
}
}
Edit 1:
Per your recent comments and update to your original question, I take it that you have many numbers and their associated Strings involved in this program and that your need is to find the String associated with the number. If so, then you need to think re-design, that the numbers and their strings should not be hard-coded into your program but rather be part of the program's data, perhaps in a text file with one column being the numbers and the next column (separated by a space perhaps), the associated text. This way you could read in the data and use it easily in a HashMap, or data base, or really any way that you desire. This will give your project much greater flexibility and robustness.
You can use something like:
for (Field field : MyClass.class.getDeclaredFields()){
if (field.getType().toString().equals("int")){
int val = (Integer)field.get(MyClass.this);
switch (val){
case 335343:
case 234234:
System.out.println(field.getName());
}
}
}
Remember to change MyClass for your class name and that at least one instance should exist to get the value of the field. So, if you are planning on testing the code in a main method, you should change MyClass.this to something like new Myclass().
Another thing to remember is that the fields are attributes and not method variables (so it won't work if you are using this to access variables declared inside a method).
You can use enum.
If these numbers just need to be unique, you can say
public enum Yourname {
FOO, BAR, BEZ
}
and refer to the name as Yourname.FOO and the value as Yourname.FOO.ordinal(). You can use enums for if-blocks, switch-statements.
If you want to have the numbers you gave in the question, so if FOO needs to be 335343, you can create numbered enums. Have a look at is-it-possible-to-assign-numeric-value-to-an-enum-in-java and number-for-each-enum-item.
I would suggest that you print out the line number, not the variable name. That should give you enough to determine where the message is coming from. Here's more info on how to do that:
How can we print line numbers to the log in java
I had a similar problem with a long list of int variables that I had to print the name of each variable and its value (main goal was to create a text file that was going to be imported in an Excel file).
Unfortunately I'm quite new in Java programming, so the only solution that I found (probably wrong) is to use two different arrays: one String array for the String name and another Int array for the corresponding values.
For example:
int varName01, varName02, ....
String[] listNames = new String {"varName01", "varName02", .....
int[] listValues = new int {varName01, varName02, .....
for (int i=0; i<listValues.length;i++)
{
print String.format("%s %d", listNames[i], listValues[i]);
}
Probably this is not the correct way to do it, so any opinion from some Java expert would be more than welcome. Thanks!

Categories