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.
Related
I'm new to coding and I've faced this problem recently: I'm working on a class which has various fields, and I want to insure each instance of the class has a unique value for a certain field using static variables. for example, consider this class:
public class NetworkNode {
private String NodeName;
private int NodeNumber;
private boolean NodeAttraction;
....
}
in the code above, I want to insure each object created from the class NetworkNode to have a unique and different NodeNumber or in other words, no two NetworkNode objects should have the same NodeNumber field.
what are the ways to do this? thanks.
You could automatically assign a different NodeNumber to each instance if you don't care about the actual value as long as it's unique. Using static variables you could create a private static counter nextNodeNumber in your class NetworkNode:
private static int nextNodeNumber = 0;
In your constructor you could then do
public NetworkNode() {
this.NodeNumber = nextNodeNumber;
++nextNodeNumber;
...
}
This way you just have to ensure, that there is no other way to set/change NodeNumber or nextNodeNumber.
If you are using multiple Threads you would have to secure access to nextNodeNumber to prevent asynchronous access.
1 put a
static Set<String> myuniquevalues ... (for example) for each of your fields
2 in your constructor
public NetworkNode (String value1 ...)
{... check if value1 exists in myuniquevalues , and throw exceptions }
3 if your objects are deleted, you must manage it also ...
Alternative: concentrate creation of your objects in a factory, and manage unicity there.
I recommend you to do some reading about variables and what static means. To make it short, a static variable exists only "once" in your program.
For example, if you create a game, you want the variable score to be static since there will only be one instance of this variable.
In order to have each NetworkNode to have a unique and different NodeNumber, you have to construct the object like this:
public NetworkNode(String NodeName, int NodeNumber, boolean NodeAttraction){
this.NodeName = NodeName;
this.NodeNumber = NodeNumber;
this.NodeAttraction = NodeAttraction;
}
See, here, each NetworkNode will have a different value for each of the variables passed as parameters.
You will then just need to create the object in your main function or whatever like this for example:
NetworkNode myNode = new NetworkNode("node1", 0, true);
Hope it helps,
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--) { ... }
Ok my problem isnt really a serious one, im just trying to find a clever way of access/modification of class member variables. Here is the code:
public class Storage{
private int cookies= 0;
private int rolls= 0;
private int candies= 0;
private int lolipops= 0;
private int iceCreams= 0;
public void addCookies(int howMuch){ //this is the dirty way of creating method for
this.cookies = cookies+howMuch; //every member variable
}
public void addValue(String stat, int howMuch){ //i would like to do it only
//by passing the name
//of variable and then cast it as integer
//so that it would relate to my class members
int value = this.(Integer.parseInt(stat)); // <- YES i know its ridiculous
//im just trying to explain what is my aim
value = value + howMuch;
this.(Integer.parseInt(stat)) = value;
}
}
Generally i would like to access a field by passing its name to a method, read value of that member, add to it some value, and then store it. Yes i know that it easily can be done with separate methods, or even with one by using some arraylist and comparisons of member names with parameter passed to method. But i would like to do it "fast" without redundant code writing.
Now i have like 5 members, but what about 15000? My aim is to simplify the whole processing and code writing. So generally is it possible to do such redundant code writing bypass? Since i know that i will always pass appropriate name to method... Unless the rule of thumb is to create method for each variable?
Normally you would use a collection like a Map.
public class Storage{
private final Map<String, Integer> inventory = ...
public void addCount(String key, int count) {
Integer i = inventory.get(key);
if (i == null) i = 0;
inventory.put(key, i + count);
}
I guess that by using reflection you can iterate through the fields/methods of your object and do your computation.
For one specific field:
Field member = myObject.getClass().getField(fieldName);
// If you know the class: Field member = MyClass.class.getField(fieldName);
System.out.println(member.getInt(myObject)); // Get the value
member.setInt(myObject, 4); // Set the value
If you want to something for all the public members:
for(Field member: myObject.getClass().getFields())
// Or you can do: for(Field member: myClass.class.getFields())
{
member.getInt(myObject)); // Get the value
member.setInt(myObject, 4); // Set the value
}
Basically, what you do is that you find the Field object that represents the members of you object, then you can manipulate it.
Most IDEs will generate setters and getters for you. This will do what you want with no bother or effort. If this is insufficient, write a method which uses reflection to set the values.
If you have a class with 15000 members, and by this I assume you mean variables private to a class, then you have other issues to resolve.
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.
}
}
The definition of immutability states that the state of an object (its data) cannot be altered after construction.
Here lays the question, in my opinion the state and the data the object contains are different things.
Maybe the state means the data that is provided via getters?
It does not mean data marked private and not visible to the outside world, that can indeed change and not alter the state of an object.
Tell me if this is correct:
final class Obj1 {
private final int i;
private final Random rnd = new Random();
private int j = rnd.nextInt(1000);
public Obj1(int i) {
this.i = i;
}
public getI() {
j = rnd.nextInt(1000);
return i;
}
}
An instance of Obj1 is an immutable object.
final class Obj2 {
private final int i;
private final Random rnd = new Random();
private int j = rnd.nextInt(1000);
public Obj1(int i) {
this.i = i;
}
public getI() {
return i;
}
public getJ() {
return j;
}
}
Is an instance of Obj2 a mutable or immutable object and why? What if we get the next Random in the body of getJ each time the getter is invoked?
And what about such a class? Mutable/immutable and why?
final class Obj3 {
private final Random rnd = new Random();
private int j = rnd.nextInt(1000);
public Obj1() {
}
public getJ() {
return j;
}
}
What about this one? Mutable/immutable and why?
final class Obj4 {
private final Random rnd = new Random();
public Obj1() {
}
public getRnd() {
return rnd.nextInt(1000);
}
}
An important point about immutability is that the obeservable state of the object must not change.
A very good example is java.lang.String, which is often quoted as the canonical example for an immutable class. It has a single non-final field, which is hash. hash holds the hash code, but defaults to 0. The hash code is calculated lazily the first time hashCode() is called and cached in that field. This way the internal state of a String object can change, but the observable state never changes (because hashCode() always returns the same value, no matter if it is calculated or just returning the cached value).
This means that the first three samples you provided (Obj1, Obj2, Obj3) are immutable: They have no setter and nothing else can change the value returned by their methods after the construction (it would be a good idea to declare the fields final, but it's not a requirement for immutability). Note also you can also leave out the Random field entirely in those classes, as it's not used after construction anyway.
I'd say the last sample (Obj4) is definitely mutable, because you change the state (i.e. what the next getRnd() call returns) each time you read from it (i.e. each time you call getRnd()).
So, to answer the question in the title: yes, a class referencing a Random object can be immutable, if the state of the Random object is not observable in the state of the class itself.
Good question. But this is question of terminology, while immutability is more about how you can use objects. Benefits of immutable objects:
You can pass them by reference and be sure no one change its state;
You don't need to think about synchronization;
More secure to use as keys in hash maps.
I would not state object as immutable if it changes it's state after construction, even if it has to setters.
It is perfectly legitimate for an immutable object to hold, and even expose, references to objects of arbitrary type if the references are recognized as identifying, rather than holding, the objects in question. For example, consider an object reference as being analogous to a VIN (Vehicle Identification Number--an alphanumeric string that uniquely identifies a vehicle, at least those manufactured in, or imported to, the U.S.), and imagine a repair shop might keeps a list of the VINs of the cars it has serviced. The cars themselves would hardly qualify as immutable objects, but the list wouldn't hold cars--it would identify cars. One could not look at a VIN and know what color a car was at the time it was serviced, but when a car enters the shop one could use the list of VINs to determine whether the car had visited before.