Casting string as a integer member, possible? - java

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.

Related

how to insure a certain field in a class has different and unique values in all instances in java?

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,

Making a variable unchangeable once stored

EDIT-
Sorry I may have been unclear in what im asking, the code works in finding the maximum. But once its stored how would I set the variable so If I wanted to change it in the future I can't
First: Declare your final variable without an initial value.
Second: Use a temporary variable to compute the unique value.
Last: Load the temporary value into your final variable.
If it is an instance variable, you'll have to do this computation into every constructor.
Update
class MyClass
{
private final int patientID;
public MyClass()
{
int temp = IDCount;
for (int i=0; PatientInfo.contains(temp) && i < 9999999;i++){
temp++;
}
this.patientID=temp;
}
}
As you initialise the value to zero you check if it is zero and if so it can be updated.
if (patientId == 0) patientId = IDCount +1;
Of course to make this more robust, the patientId should be a private field in another class and the setting should be done in a setter with the above logic.
On a further note, if you are simply want to get use the maximum value, consider using Math.max
You can create somewhere (probably in the PatientInfo class) a static field representing the current maximum PatientID.
Then just assign that number+1 to the newly created Patient and change the maximum.
The thing you want to seems to be pointless. I think you might just want to implement unique constraint on the specified attribute. But if you really want an "once mutable int", you got it:
class CustomInt {
private Integer val;
public void setVal(int val) throws Exception{
if(val != null)
throw new Exception("cannot reassign");
this.val = val;
}
}
But as I marked, it is pointless.

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.

Object in Object Array doesn't want to store my data

fairly new to this language. Long time lurker, first time question asker.
In my program, I load a bunch of strings from a text file and then pass all of that information inside of a String array to a program that takes the data point by point (it comes in a reliable pattern) and assigns it to variables inside a class.
I use this loop to create the objects.
Gladiator[] gladiator = new Gladiator[(match.contestants)];
for ( int a = 0; a < match.contestants; a++) {
gladiator[a] = new Gladiator();
gladiator[a].populategladiators(parsedInfo,a);
}
Gladiator class full of public final variables which are defined in the method populategladiators. The syntax is as follows:
this.name = parsedInfo[0+mod][0];
this.culture = parsedInfo[1+mod][0];
this.background = parsedInfo[2+mod][0];
etc.
At the moment, I only load two gladiators and it seems like maybe both are being set at once with both pass throughs? Anyone have any thoughts on this?
Also, in another method in class Gladiator, should I be able to call this.name and be okay to get data about the object I specified when calling the method?
Edit: Trying to make the code look right. Giving up since there isn't much.
2nd Edit: Example of variable declaration in gladiator class:
public static String name;
public static String culture;
public static String background;
I had my variables set as static, thus it wasn't allowing me to set individual variables for the objects. I just didn't understand what the static keyword meant.

global data, static and new

Basic question from somebody coming from structured into object programming... hoping not to be too basic.
I want to have a large array of data that is been shared by different classes inside my application.
What's the best practice to do this?
Is this correct?
public class LargeData {
private static long[] myData;
private static final int MAX = 100000;
public LargeData() {
myData = new long[MAX];
// ... initialize
}
public long getData(int x) {
// ... do whatever and return a long
}
}
And if this is correct, how is the correct way to access this data from any of my classes? Should I make a
LargeData ld = new LargeData();
inside every single class that wants to access to myData?
Thank you and sorry for being too easy... :)
use a Singleton pattern for this.
Everytime you call
LargeData ld = new LargeData();
in your code, you will be effectively calling
myData = new long[MAX];
which is wrong.
What you can do is:
public class LargeData {
private static final int MAX = 100000;
public static long[] myData = new long[MAX];
}
and access it as LargeData.myData from anywhere.
initialize array immediately. with current implementation you won't be able to use static array until create object of LargeData.
Also if class just for holding array prevent its instantiation and extension by making it final and constructor as private.
public final class LargeData {
public static long[] myData = new long[100000];
private LargeData() { }
}
And get access as LargeData.myData
Assigning values to static variables from instance constructors is a bad idea without a null check - if you ever instantiate two objects from this class the second will cause you to lose all data stored in the array (you lose the reference to the old array when the second instantiation overwrites the static reference). With null check it is also a bad idea though, unless you really really really need the data in one instance sort of a "global variable" way. It is best to think of static references as global variables which can be either viewable by all (if they are public) or visible only from the class you define it in (private) or something in between (protected or package protected access). You pretty much want to avoid using them though in almost all cases and use the Singleton pattern instead of static variables inside classes. With the Singleton pattern you use instance variables and non-static getters to get to the data.
However I do not see given the things you wrote why you would need a singleton pattern for this particular problem - you just want to store data in an object and share that object around, right?
You can fix the posted code like this without static keywords and this allows multiple LargeData instances to be alive at once in your application:
public class LargeData {
private long[] myData; // instance variable to store the data
private static final int MAX = 100000; // max length
public LargeData() {
myData = new long[MAX];
}
public long[] getData() {
return myData;
}
}
Then you can use the data as:
LargeData ld = new LargeData();
long[] = ld.getData();
And you can use the reference stored in ld any way you like, you can pass it around your other classes, etc.
A better idea would be to not expose the array, rather create an API through which you use the stored data. For example:
public long getLong(int n) { return myData[n]; }
public void setLong(int n, long value) { myData[n] = value; }
Now if you don't want to pass around the reference to the LargeData instance stored in ld, you can use a static variable in LargeData to store the reference and a static getter which lets you access it from any other java code. If you need multiple LargeData instances to work with you can create a LargeDataRegistry class that encapsulate a Map where you would store each instantiated LargeData instance.

Categories