Using class variables in methods - java

In java how to use class variables in methods?
this is the code that I have
public class ExamQ3a {
String[] descriptionArr = new String[50];
static int[] codeArr = new int[50];
public static void displayItems(int count, int[] codeArr,
String[] descriptionArr) {
count = this.codeArr.length;
for (int i = codeArr.length; i < codeArr.length; i--) {
}
}
}
The line that is being highlighted here is the count = this.codeArr.length; the error that I am getting is that the non-static variables cannot be referenced from a static context. But I already made the variable static. So what gives?
So as per request only! not that I want to ask the whole question, just to know why I want to use static, this is a practice question
You are to develop a simple application system to manage the inventory
in a company. The system should be able to maintain a list of up to 50
items. Each item has a unique integer code and a description.
(a) Write Java statements that declare and create two arrays to store the
code and the description of the items.
(b) Write Java method with the following method signature:
public static void displayItems(int count, int[] codeArr, String[] descriptionArr)
This method displays the code and description of all items in the company
in tabular form with appropriate column heading.
Parameters: codeArr: the array that stores the codes of the items
descriptionArr: the array that stores the descriptions of the items
count: the number of items in the system

There is no this in the static world. Get rid of it. To explain, this refers to the current instance, and when you're dealing with static methods or variables, you're dealing with items associated with the class, not with any one particular instance. So change the code to:
count = codeArr.length;
Edit 1
As an aside, you don't want to bunch up your closing braces like } } } which makes your code very difficult to read and follow. White space is free, so might as well use it judiciously to improve code readability.
Edit 2
You state:
so how would I reference the array codeArr to the class variable codeArr?
You're inside of the class, and there's no need to use the class variable name here since it is assumed to be used. Just use the static variable or method name and you should be golden.
Edit 3
Your use of static for this type of variable gives the code a bad smell. I'm thinking that your entire program would be much better off if this were an instance variable and not a static variable. For more discussion on this, you may tell us why you decided to make the variable static.

Is you're going to reference a static variable having the same name as a method parameter you prefix the static variable with the name of the class. In this case it would be ExamQ3a.codeArr.
The other way to handle this is to pick different names for your method parameters, or start using a common prefix for instance/static variables.

Another point to note is that, in the following piece of code statement1 will never be executed:
for (int i = codeArr.length; i < codeArr.length; i--) { statement1; }
it should be either
int length = codeArr.length;
for (int i = 0; i < length; i++) { ... }
or
int length = codeArr.length;
for (int i = (length-1); i > -1 ; i--) { ... }

Related

Sorting an object array into another array based on a variable

I have a problem with a program I'm writing for a school assignment.
Essentially, before this piece of code, I already recieve and work with a bunch of information that I store into an array of objects. Now I have to sort this array (after it's sorted, I will have to calculate some things in the order of the PRIORITY variable).
presume I already have a MyClass[] array called input, that stores a finite amount of MyClass objects.
MyClass[] priorityArray = new MyClass[input.length];
for (int i=0; i<priorityArray.length; i++) {
int maxIndex = 0;
int maxPrivilege = input[i].returnPrivilege();
for (int j=1; j<input.legnth; j++) {
int currentPrivilege = input[j].returnPrivilege();
if (currentPrivilege > maxPrivilege) {
maxPrivilege = currentPrivilege;
maxIndex = j;
}
}
priorityArray[i] = input[maxIndex];
input[maxIndex].setPrivilege(-900000000);
}
the MyClass class if nothing fancy, but of course, contains a proper constructor, getter and setter methods and an integer variable "privilege".
I'm getting an error in my final tests of the program and, seeing as the program returns privileges as "-900000000", it has to have something to do with this part of the code.
It's also not even writing certain MyClass instances from the input array into the priorityArray array.
How can I clead this up? Help.
I'll rewrite my answer totally.
In this line
priorityArray[i] = input[maxIndex];
You are assigning object from one array to another array by reference. It means that there is only one object and you set value to -9000000 in the next line to it. Of course element in priorityArray will have the same changes. To fix it you need to clone your object here.

Compute number of times instance variable is increased

I'm setting an instance variable to a unique value,
i.eprivate int registrationCourse = 2015000; in an object class.
I want to increase this course number by 1 each time it is called from a main method so it becomes 2015001, 2015002, etc.
I think to do this, I have to create a class variable and initialize it to 0, simply because it is not bound to a class. (Please correct me if I'm wrong)
i.e private static int numCourses = 0;
Then I have to make a constructor, and initialize the other instance variables, and increment the registration number in the following fashion:
numCourses = registrationCourse;
numCourses++;
However, I am super new to dealing with constructors, so I do not understand why I don't have to make a whileloop to do this. My other question would be when I try to return the registrationCourse number, for both cases, it obviously only returns the last incremented value, and I want to return a different valued, increased by one for each object. Any explanations??
Your static value will be shared accross all instances of the class instances. If you like to maintain the actual number that is applicable during the instance-construction, you would need to copy it to a non-static (instance-bound) variable.
For example:
class c{
private int registrationCourse = 2015000;
private int incrementalValue = 0;
private static int nextIncrementalValue = 0;
public c(){
nextIncrementalValue +=1; //increase static, shared value.
this.incrementalValue = nextIncrementalValue; // set CURRENT value for later reference.
}
}
If you now would construct 3 instances of c, each of them would have the same value for nextIncrementalValue (= 3) because they all share the same static variable, but any instance would have it's own incrementalValue (= {1,2,3})
For your question about constructors, you don't need a while loop because your application is only concerned of counting how many objects are created. And for each object, the constructor gets invoked, therefore you only need the increment code in the constructor. You would probably need your while loop in your main() code if you decide how many objects you need to instantiate:
int i = 0;
while(i<10) {
Course course = new Course(); // assuming your class is named Course
}
This will increment the counter 10 times.
For your second question on returning the value per object created, you would need an "instance" variable for this. So create another non-static variable and save the numCourses value in it:
static int totalCourses = 2015000;
int courseNumber = 0;
public Course() {
totalCourses++;
courseNumber = totalCourses;
}
So, what happens here is that the totalCourses just keep on incrementing every new object that you have. then each course number is saved and different per object.
Hope this helps.

How to use method in the name of variable?

I have to create a few variables like: "n23, n4, n18...".
So, they consist of two parts: letter "n" and a number witch I want to get from my method for generating random numbers(rand()).
Something like this:
for(int i = 0; i < 6; i++) {
int n*here_must_be_random_number_got_from_my_method*;
}
Is it possible to do something similar?
Java is no script language.
All identifiers, which means all package names, type names, method names, field names and variables, must be specified at compile time. So there is no way to concatenate your variable names based on values calculated at runtime.
BUT!
You do not even need to. Just use a java.util.Map. Instead of doing
int n*here_must_be_random_number_got_from_my_method* = *whatever_it_is_you_want_to_put_here*;
you can instead do
Map<Integer, Integer> myMap = new HashMap<>();
once, then put values inside the map like so:
myMap.put(*here_must_be_random_number_got_from_my_method*, *whatever_it_is_you_want_to_put_here*);
and get it back like so:
myMap.get(*here_must_be_random_number_got_from_my_method*);
You can't, but presumably you want to refer to these later, and if you were intending to refer to n123, then you can hopefully refer to them as n[123] instead. If that's the case, then you can use a java array, perhaps like this:
private int[] n = new int[999];
void populate() {
for(int i = 0; i < 6; i++) {
n[here_must_be_random_number_got_from_my_method] = something;
}
}
Note that java doesn't do sparse arrays, so the size of your array needs to be as large as the largest random number. If this us large, consider using a map as per Jan's answer.

In Java, Is it possible to concatenate the value of a variable into a variable name (Sounds messed up, but please read details)

Basically I have a variable, zlort = one;
I want to concatenate the value of zlort into a variable (object reference) name.
Like
BankAccount Accountzlort = new BankAccount;
I want the zlort in Account.zlort to actually be the replaced with value of zlort (one--meaning I want the value to be Accountone), and not zlort itself.
Is it possible to do this?
Thanks!
No you can't, but you might put the instance in a map:
Map<String,BankAccount> map = new HashMap<String,BankAccount>();
map.put("Account" + zlort, new BankAccount());
If you mean dynamically choosing the name to assign a variable to, then no.
You could use a HashMap to achieve the same effect.
It is not possible to change the name of a variable at runtime. That would lead to extreme security and stability problems when dealing with any real-world application.
However, as the two answers here have mentioned, a HashMap might acheive what you are looking for. (See the javadoc!!)
A HashMap (or any other map, for that matter) maps a Key to a Value. The concept is similar to a variable, which is a name -> value mapping. The only difference is that variables are part of the actual program code, which is effectively unmodifiable after compiling. A Map is a data structure that can be modified by the running program. This allows you to freely add key-value pairings to it.
Note that in Java, type-safety is encouraged through the use of Generics. Basically this ensures that the key can only be of one type (e.g. String) and the value can be of only one type (BankAccount). A thorough coverage of Generics can be found here.
You would declare this as follows:
Map<String, BankAccount> accounts = new HashMap<String, BankAccount>();
And then to add a key-value pair to the map, you would use the put() method (which 'puts' a value into the map, associated with a key)
String key = "Key"
BankAccount value = new BankAccount();
accounts.put(key, value);
To retrieve it, you would use the get() method.
BankAccount retrievedValue;
retrievedValue = accounts.get(key);
After reading the explanations in your comments, the fact that you can't use an array but can use an `ArrayList'...
Rather than creating a new variable name (or array element, or map value) for each BankAccount, you can probably use scope to your advantage.
Scope is the concept that a reference to a variable only has meaning within a certain part of code. If you declare a variable inside a method, that variable can only be seen within that method. A variable declared within a block (a loop, if statement, etc ) can only be seen from within that block.
Class fields have a different kind of scoping that can be adjusted with keywords (see here).
For example:
public class ScopeExample
int classInt = 10;
public void method() {
int methodInt = 0; // This integer can only be seen by code in
// this method
}
public void method2() {
//doSomething(methodInt) // This line won't compile because i is
// declared in a different method!
doSomething(classInt); // This line will compile and work
// because x is declared in the class that
// contains this method.
int index = 0;
while (index < 3) {
int whileInt = index; // This integer can only be seen from within
// this while loop! It is created each
// loop iteration.
doSomething(whileInt);
}
doSomething(whileInt); //This line won't work, whileInt is out of scope!
}
public doSomething(int a) {
System.out.println(a);
}
}
SO! If you create a BankAccount object within the loop, you don't have to worry about creating a new name for the next one. Each time the loop iterates it will become a new object (when you create it).
If you have to store it, you definitely will need to use an array or other data structure (ArrayList!).
Building on the idea of scope, you -can- have the same variable name for each new BankAccount. A variable reference name isn't guaranteed to be paired with the object that it refers to. That is a convenience to the programmer, so you don't have to know the exact memory address it is being stored in.
For example:
public static void main(String[] args) {
Object o;
int i = 0;
while (i < 5) {
Object reference = new Object(); // Create a new Object and store
// it in 'reference'
o = obj; // The Object 'o' now refers to the object in 'reference'
i++;
}
System.out.println(o); // This should print information about the
// LAST object created.
}
The new Object created in the loop does not belong to 'obj'. You as a programmer use 'obj' to point to the Object. The program doesn't really know what obj means, other than the fact that it points to the Object you just created.
Finally, you can use this along with an ArrayList to make your life easier.
public static void main(String[] args) {
// Our new ArrayList to hold our objects!
ArrayList<Object> stuff = new ArrayList<Object>();
int i = 0;
while (i < 5) {
Object obj = new Object(); // Create an object and make obj point to it.
stuff.add(obj); // Put "the object that 'obj' points to" in 'stuff'.
i++;
}
// This loop goes through all of the Objects in the ArrayList and prints them
for (int index = 0; index < stuff.size(); index++) {
System.out.println(stuff.get(i)); // This will print a single
// object in the ArrayList each time.
}
}

in java, is it possble to name an array from a string?

I am a beginner with java, and I was wondering is if is possible to name and create an array from the value of a string.
Here is what I have:
public static void array(){
createArray(array1, 100, 100);
}
public static void createArray(String name, int r, int c) {
int[][] name = new int[r][c];
}
I hope that explains itself. Thanks
EDIT: The code above does not work. I just want to know if it is possible to do what is above
EDIT2: As a beginner with java, I am just watching tutorials, and creating programs with what I learned to make sure I understand what is being taught. I first created a program which creates s multidimensional arrays. It then calls a method which assigned values to the array, (row+1)*(column+1). This makes a table much like a multiplication table. Then it displays the table to the screen.
After I created that program, I wanted to be able to create arrays much like I assigned the values to it. So i asked this question...
Here is my code:
public static void array(){
int[][] array1 = new int[100][100];
int[][] array2 = new int[20][20];
setArrayValue(array1);
setArrayValue(array2);
drawArray(array1);
System.out.println();
drawArray(array2);
}
public static void setArrayValue(int x[][]){
for(int row = 0; row<x.length; row++){
for(int column=0; column<x[row].length; column++){
x[row][column]= (column+1)*(row+1);
}
}
}
public static void drawArray(int x[][]){
for(int row=0; row<x.length; row++) {
for(int column=0; column<x[row].length;column++){
System.out.print(x[row][column] + "\t");
}
System.out.println();
}
}
Your concept doesn't make sense.
You might want to use a Map<String, int[][]>, which will map names to arrays.
What you are trying to do is not possible in Java. In the createArray method, name is of type String and cannot be redeclared as an int array.
Perhaps you are interested in a Map that uses String objects as keys? The values could be int arrays (or any other object).
No, you can't do that.
Variable names are not variable in Java.
Furthermore, local variables even lose their names when the code is compiled. Variable names are just a help for the programmer to distinguish between variables.
Nop can't be done. Variable names need to be known before hand.
No, it is not possible. You might be able to accomplish your task with a TreeMap or another Map implementation instead.
Instead of saying
name = something;
You would say
map.put(name, something);
Instead of
name[0] + 7
You'd say
map.get(name)[0] + 7
As stated by others - this cannot be done. That is because Java compiler needs to know exact name of a variable at the compile time. This is mandatory, since otherwise Java compiler wouldn't know which variable you are addressing, so it couldn't perform, for instance, type-safety checks.
However, if you just wish to stamp your variable with some unique ID, I guess the solution is closest to what has been stated by SLaks. Simply use Map, and You should be good. Example below.
Map<String, int[][]> myMap = new HashMap<String, int[][]>();
myMap.put("someUniqueName", new int[][] {{0,0}, {1,1}});
and later on:
int[][] array = myMap.get("someUniqueName");
Hope that helps achieve what You want.
Strictly: almost ;-) You can add a dynamic field in a class, which could be an array, using AOP. But...
It's difficult.
This solution is too complicated in most cases. You could probably solve your real problem in a much easier way.
Some advice: start with the beginning... and try using List (interface) / ArrayList as much as possible unless you have some pretty good reason to use an array.

Categories