I have been given a starting code to work on a project, however I am confused about the following code and cant seem to find any examples online!
public static Entity[][] read(){ ... }
How can I handle this Entity to add new entries to an array, and then how can I return this?
The following constructor is invoked by a different class.
public World() {
aWorld = new Entity[SIZE][SIZE];
int r;
int c;
for (r = 0; r < SIZE; r++) {
for (c = 0; c < SIZE; c++) {
aWorld[r][c] = null;
}
}
aWorld = FileInitialization.read();
}
I feel it would be much simpler if the array was just a parameter or if it were something like:
public static int[][] read(){ ... }
UPDATE:
The goal is to read from a file in the method read() and then assign the an entity to the correct location based on the location in the file. But I am not able to assign since the data types would be incompatible, Required is Entity, but I want to be able to set it to an int, char or String.
To add to an array of objects, you do exactly what you would with an array of primitives (e.g. ints), you just use Entitys. So if you want to add something to aWorld you use
aWorld[r][c] = new Entity(...); //with provided constructor's parameters
// or
aWorld[r][c] = existing_Entity; //for an Entity variable you already have
When you're done adding, you simply return the array aWorld.
If FileInitialization's static read() is going to return Entity[][], that's an entity array by itself. It means that you shouldn't iterate aWorld, rather assign the return value to it directly like
aWorld = FileInitialization.read();
Inside the read(), use that for loop you've made in the constructor and add a new Entity object as noted by Linus
Alright I would like to say thanks to all of you here as I was set on the right direction. But I would like to share my answer which should be simple and hopefully make someones life easier in the future.
To initialize the array of objects just do it as you would initialize any other array, in this case:
Entity[][] reference_name = new Entity[SIZE][SIZE];
To return this value, simply return the reference:
return reference_name;
Now the part where you actually modify an entry into your array.
Lets say you have something like
public static void Entity[][] read() { .. }
you need to create a class file Entity.java (same name as the array type being passed)
In this case it would look something like this:
public class Entity {
private char appearance;
public Entity(char anAppearance) {
appearance = anAppearance;
}
now to give this array an entry do something like this:
reference_name[0][0] = new Entity('X');
alright and in case you are wondering how to display this just add an accesor method to class Entity.
public char getAppearance() {
return(appearance);
}
and to output:
System.out.println(reference_name[0][0].getAppearance(); );
Related
public void setData(double[] d) {
if (d == null) {
data = new double[0];
} else {
data = new double[d.length];
for (int i = 0; i < d.length; i++)
data[i] = d[i];
}
}
this method in my code is used to set the data of an array. I am also required to write a method called reset() that changes a given array to have a null value. Also, we are practicing overloading in this lab. There are four versions of setData() (double, int, float, long). Since a double array is used internally by the Stat class to store the values, do I only have to make one reset() method of type double?(I think I only need one...) Finally, please give me some hints as to going about this reset business because everything I have tried has failed miserably and usually consists of statements such as
"setData(double[] null)" which return errors.
Everything in java is pass by value; even references are passed by value. So by passing an array through a method, you can change the contents of the array, but you cannot change what the array points to. Now, if you are inside a class and happen to pass an instance member that you already have access to by virtue of being in the class, you will be able to set the array to null.
If you always want to be able to change what an array points to, then simply have a function which returns an array (instead of being void), and assign that returned value to the array of interest.
Because java is pass by value, you can't reassign a variable passed as a parameter to a method, and expect to see that change reflected outside.
What you can do, is put the array in some sort of wrapper class like this:
class ArrayReference<T> {
T[] array; // T would be either Double, or Long, or Integer, or whatever
}
and then:
void setData(ArrayReference<Double> myReference) {
myReference.array = null;
}
I'm not sure if I understood your question, but is it that what you want?
public class Stat {
private double[] data;
public void reset() {
data = null;
}
public void setData(double[] d) {
data = (d == null) ? new double[0] : Arrays.copyOf(d, d.length);
}
}
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.
}
}
I have a problem with getting a new value of an object. I have a code like that:
...
TimeSchedule[] offspringScheduleOne = new TimeSchedule[AVAILABLE_CLASSROOMS];
...
offspringScheduleOne[i] = genes.get(geneOneIndex).getSchedule()[i];
...
After that assignment offspringScheduleOne[i] and genes.get(geneOneIndex).getSchedule()[i] points the same memory address. I want that: offspringScheduleOne[i] should get the value of the genes.get(geneOneIndex).getSchedule()[i], they musn't be same, they just should have same values.
TimeSchedule class:
public class TimeSchedule extends AlgorithmParameters {
public int[][] timetable = new int[DAYS][HOURS];//DAYS and HOURS are static final variables that comes from AlgorithmParameters
public int[][] getTimetable() {
return timetable;
}
public void setTimetable(int[][] timetable) {
this.timetable = timetable;
}
}
How can I do that?
It actually is copying the value - but you need to understand what that value is.
The value of offspringScheduleOne[0] isn't a TimeSchedule object. It's a reference to a TimeSchedule object. No expression in Java has a value which is an object. It's really important that you understand this.
Now, if you want a copy of the object, you'll have to make that happen yourself. For example, you could include a clone() method in TimeSchedule, and write:
offspringScheduleOne[i] = genes.get(geneOneIndex).getSchedule()[i].clone();
In other words, create a clone of the existing object, and then set offspringScheduleOne[i] to be a reference to that newly created object. Of course, if any of the fields within TimeSchedule is a reference type field, you'll need to consider whether or not you need to clone that object as well...
... or you could add a constructor and call that, or another method, etc. But you need to be absolutely clear that the assignment operator is copying the value, but that value is a reference.
EDIT: Okay, now that you've posted TimeSchedule, a few suggestions:
Stop using public fields. What's the point of having properties if the field is public?
Rather than having properties returning the whole array, change them to access an individual hour, e.g.
public int getTimetable(int day, int hour) {
// TBD: Argument validation
return timetable[day][hour];
}
// Similar for `setTimetable`
Create a clone method like this:
public TimeSchedule clone() {
TimeSchedule copy = new TimeSchedule();
for (int i = 0; i < timetable.length; i++) {
copy.timetable[i] = timetable[i].clone();
}
return copy;
}
(That's slightly wasteful in that it will create the subarrays and then discard them, but let's get something which works first...)
}
public Test clone() {
int[][] timetableCopy = new int[timetable.length][];
for (int i = 0; i < timetable.length; i++) {
timetableCopy[i] = timetable[i].clone();
}
return null;
}
You should create a new TimeSchedule object. Assuming you have a copy constructor you can use this:
TimeSchedule original = genes.get(geneOneIndex).getSchedule()[i];
TimeSchedule copy = new TimeSchedule(original);
offspringScheduleOne[i] = copy;
The constructor should copy the values from original. If you don't have such a constructor you can call get and set methods to copy the values across manually.
TimeSchedule original = genes.get(geneOneIndex).getSchedule()[i];
TimeSchedule copy = new TimeSchedule();
copy.setFoo(original.getFoo());
copy.setBar(original.getBar());
// etc...
offspringScheduleOne[i] = copy;
There's also a clone method that was designed for creating copies of objects, but it's awkward to use and it's probably best to avoid it.
You could let TimeSchedule override the clone method and write
offspringScheduleOne[i] = genes.get(geneOneIndex).getSchedule()[i].clone();
I have a readData() function that reads files a returns a few different objects of parsed data. Right now, the return type of readData() is Object[]:
Object[] data = readData();
MyGenome genome = data[0];
Species[] breeds = data[1];
//etc
This feels awkward. Is there a better way to return this data? I don't want to have separate functions like readGenome() and readSpecies() because that would require iterating over the files twice. Also, I'd rather wrap up all the gathering of data in one function.
A similar issue: a function that returns a match of at least four characters between two strings:
public int[][] findMatch(String g0, String g1) { /* cool stuff */ }
//...
int[][] bounds = findMatch("ACOIICOCOCICOICA", "AOCCCCCCICCIIIIIOIAOCICOICOICA");
where bounds[0][0] is the left bound on the g0, bounds[0][1] is the right bound on g0, bounds[1][0] is the left bound on g1, etc. This also feels sort of awkward. It is difficult to code with the result without continuously looking up the keys.
Create a new Class:
class MyAnalysedGenome {
MyGenome genome;
Species[] species
...
}
and return that. You'll probably find you have other functionality that should go in there too. Perhaps the code that surrounds your getData() call.
How about using a strongly typed class to represent the complex return type of readData()?
public class Taxonomy
{
public MyGenome genome;
public Species[] breeds;
//etc
{
Taxonomy data = readData();
You can do the same thing for your search bounds problem
public class SearchBoundary
{
public int left;
public int right;
}
SearchBoundary resultBounds = findMatch(searchBounds);
For the first issue,couldn't you simply use an intermediate data representation ? I mean you could read your file once, which would give you the file content (that you could format the way you want), and then create two methods readGenome() and readSpecies() that would take this file content as a parameter.
You can create a class that have genome and species as fields.
...
class DataToBeRead {
MyGenome genome;
Species[] breeds;
}
...
DataToBeRead data = readData();
MyGenome genome = data.genome;
Species[] breeds = data.breeds;
You can make the class private if you do not think anybody else will used it or make it public if someone else will use it.
You can also make it static if you do not want to create a separate file for it.
Hope this helps.