Editing fields of an object 2d array in java - java

The goal is to copy some Tile objects and custom properties into a 2D array, however I got unexpected results :
for (int i = 0; i<3; i++)
{
for (int j = 0; j<3; j++)
{
TileList[i][j] = Tiles[3];
//the goal is the overwrite the MapX and MapY fields of each element of the new Array
TileList[i][j].MapX = i;
TileList[i][j].MapY = j;
}
}
After printing out the values each element each MapX and MapY field of each element was expect to have their own separate value, however instead both MapX and MapY are set to 3 for each tile object reference in the 2d Array.

You're setting all the array members to the same object with this statement:
TileList[i][j] = Tiles[3];
That statement copies a reference to an object, not the object itself.
On the last pass through the loop, all the array members point to the same object, and these statements set its members to 3 and 3:
TileList[i][j].MapX = i;
TileList[i][j].MapY = j;
If you want all the array members to point to different objects, you can create a new object for each with a default constructor:
TileList[i][j] = new Tile();
Or a constructor which copies another object:
TileList[i][j] = new Tile( myDefaultTile );
Or the clone() method, if you support it:
TileList[i][j] = myDefaultTile.clone();
As an aside, note that it is customary in Java for the names of variables and class members to begin with a lowercase letter. For example:
tileList[i][j].mapX = i;

Related

Java array shift referencing

I tried shifting an array but I'm having issues.
The code to shift the array is as follows:
for(int i = (size - 1); i >= 0; i--)
{
data2[i+1] = data2[i];
}
Array init (Copied from another array)
obj[] data = new obj[size];
obj[] data2 = new obj[size + 1];
for(int i = 1; i <= size; i++)
{
data2[i] = data[i-1];
}
data2[0] = data[0];
For example, if size = 3, I only want to manipulate and use the data for data[1] -> data[3]. But, if the data for data[0] changes, the data for data[1] changes as well. What causes this?
ex:
Data 2[0]: 6----1----0----0
Data 2[1]: 6----1----0----0
Data 2[2]: 4----8----0----0
Data 2[3]: 9----5----0----0
data2[0].setElementTwo(3);
Data 2[0]: 6----3----0----0
Data 2[1]: 6----3----0----0
Data 2[2]: 4----8----0----0
Data 2[3]: 9----5----0----0
I'm copying the first array to the second because data[] is generated in another class which generates from 0->size, while I need 1->size+1 for this part of the program.
-edit for clarity-
full pseudo-code:
obj[] data = new obj[size];
obj[] data2 = new obj[size + 1];
for(int i = (size - 1); i >= 0; i--)
{
data2[i+1] = data2[i];
}
for(int i = 1; i <= size; i++)
{
data2[i] = data[i-1];
}
data2[0] = data[0];
// print data2 0->3
// change data2[0] value
// print data2 0->3, values would have changed for data[0] and data[1]
// but I only want to change values for data[0] and not data[1]
First, let me clarify some concepts. obj is a reference type. Variables of reference types hold references to the actual objects. When you do aRefVariable = anotherRefVariable, you are not creating a new object. Instead, you are saying that aRefVariable should hold the same reference as anotherRefVariable. Basically, the two variables points to the same object after that line is executed.
The problem lies on this line:
data2[i+1] = data2[i];
You are saying that data2[i+1] should hold the same reference as data2[i].
To simplify the situation, let's suppose i is 0, so the line now becomes:
data2[1] = data2[0];
As I said, the second and first element of data2 points to the same object now. Accessing data2[0] is exactly the same as data2[1] in terms of the object you got.
Great, let's modify the object that the first item of data2:
data2[0].setElementTwo(3);
Now the object that data2[0] is referencing has been modified. When you try to access data2[1], you see the modification as well. Why? Because data2[0] and data2[1] refer to the same thing!
To fix this problem, you need to replace this line:
data2[i+1] = data2[i];
with something like this:
data2[i+1] = new obj(...);
// you should create a new obj that has the same values as data2[i] using its constructor
The new data2[] is referencing the old data[], so changes in the old will reflect in the new.
If you don't want that use
data[index] = new obj(data[i-1]) ;
This will create a new object, which will be basically a copy of the old object and mutually exclusive from one another.

Java Creating Objects at Runtime in a For Loop

I'm trying to create objects within a for loop at runtime. Here is the (incorrect) code:
for(int i=1;i<max;i++){
Object object(i);
}
I'd like it to create max number of Object objects with names object1, object2, etc. Is there any way to do this? I have been unable to find anything elsewhere online. Thanks for your help!
You want to use a data structure to store a sequence of objects. For example, an array could do this:
Fruit banana[] = new Fruit[10];
for (int i = 0; i < 10; i++){
banana[i] = new Fruit();
}
This creates 10 objects of type Fruit in the banana array, I can access them by calling banana[0] through banana[9]
You could use an array to create multiple objects.
public void method(int max) {
Object[] object = new Object[max];
for (int i = 0; i < max; i++) {
object[i] = new Object();
}
}

Error Reading Data into Arrays in Java

I created a method that puts the read numbers into a NumberArray and in total 2 NumberArrays are created per input file. I have created an array of the object NumberRow on the line I marked with "!!!!". I put the read double into the array. However, when I read those arrays, numberRow[0] is not correct; all the values belonging in numberRow[1] are in there, and the values in numberRow[1] are correct. There is probably a simple solution, but I really don't see what is going wrong here.
Unit[] unitArray = new Unit[dataset.numberOfRecords];
double[] emptyDoubleArray = new double[dataset.numberOfRecords];
for(int x = 0; x<dataset.numberOfVariables; x++){
numberRow[x] = new NumberRow(emptyDoubleArray);
}
for(int i = 0; i<dataset.numberOfRecords; i++){
String label = in.next();
double[] elementsPerUnit = new double[dataset.numberOfVariables];
for(int k = 0; k<dataset.numberOfVariables; k++){
double misc = in.nextDouble();
!!!!! numberRow[k].NumberArray[i] = misc;
elementsPerUnit[k] = misc;
}
unit = new Unit(label, elementsPerUnit);
unitArray[i] = unit;
}
unitRow = new UnitRow(unitArray);
out.print(Arrays.toString(numberRow[0].NumberArray));
}
Arrays are objects in Java. That is, they are not copied and passed by value (like int, etc), they are passed by reference (like Object, String...)
If you create an array with new and pass it to two objects, there is still only one array (you only used new once, think about it this way). When one object edits the array, the single copy of the array, having been edited, 's edits are seen by the other object.
The solution is, create a new array if it should be distinct from all other arrays.
EDIT: You create one array here (note the new)
double[] emptyDoubleArray = new double[dataset.numberOfRecords];
this one array is passed to all NumberRows (note, no new)
numberRow[x] = new NumberRow(emptyDoubleArray);
therefore if I edit any NumberRow's array it is seen in all NumberRows.

2D Arrays and Generics Issue (Java)

I'm having an issue understanding some compiler-errors, regarding 2D arrays (ArrayList containing an ArrayList) and generics. My understanding of generics isn't the best, so I tried to research the issue beforehand and still ended up confused.
According to comments on 2D dynamic array using ArrayList in Java, you can't mix arrays with generics (or rather, you can with #SuppressWarnings("unchecked"), but are discouraged from doing so). However, I'm not sure what this exactly means.
Here is my problem code:
blocks = new ArrayList<ArrayList<BarrierBlock>>(columns); // initialize rows
for (int i = 0; i < columns; i++){
// blocks.get(i) = new ArrayList<BarrierBlock>(rows); <- ERROR = (unexpected type; required: variable, found: value)
blocks.add(new ArrayList<BarrierBlock>(rows)); // initialize columns
}
// initilize each block
for (int i = 0; i < blocks.size(); i++){
for (int j = 0; i < blocks.get(i).size(); j++){
int[] blockLoc = {location[0] + (i*BLOCK_SIDE_LENGTH), location[1] + (j*BLOCK_SIDE_LENGTH)};
// blocks.get(i).get(j) = new BarrierBlock(BLOCK_SIDE_LENGTH, blockLoc); <- ERROR = (unexpected type; required: variable, found: value)
blocks.get(i).add( new BarrierBlock(BLOCK_SIDE_LENGTH, blockLoc)); // initialize 2D array elements
}
}
The two lines that I commented out were my initial attempts at initializing the arrays. The compiler complained when I tried this and gave me the error listed. What does this error mean? I would think that both sides are of the declaration statement are variables.
After looking around, I found out that I'm supposed to use the add(E e) method of ArrayList. But what is the main difference? In the new way I'm initializing arrays, doesn't that also "mix arrays with generics"?
Get RETURNS the object at the given index, it can't be used to SET the object.
here are things you CAN do with get:
list l = new list();
item a;
l.add(a);
item b = l.get(0);
b.property = 10;
l.get(0).property == 10; //true, a is the same object as b
b = new item();
l.get(0) == b; //false, list[0] is still a, b is now pointing to a different object
l.get(0) = b; //error, you can't assign to list.get

How do I create new variables based on the size of a List?

I have a List with say size n, and I have to dynamically create n variables ie i want to dynamically create the variables depending upon the size of the list. How can i achieve this?
Say i have List as List<Integer> year with n elements in it;
then i have to create the n Integer variables from the above list.
EDIT : If i have list with 3 elements in it the i want to create 3 variables like
a = list(0);
b = list(1);
c = list(2);
like this the list may have any number of elements then i have to create those many variables. Hope I am clear now.
thanks.
You can not create n local variables as you seem to suggest. (What would their names be?)
You need to store the variables (or rather integer values) in a List or some other Collection, and populate them within a loop:
int n = year.size();
List<Integer> theIntegers = new ArrayList<Integer>(n);
for (int i = 0; i < n; i++)
theIntegers.add(i);
gives you year.size() number of integers (0, 1, 2, ...).
You can then access the integers through
theIntegers.get(4);
if you want to read the integer with index 4. and
theIntegers.set(4, 10);
if you want to update the integer with index 4, to the value 10.
You could in this case also create an array:
int[] ints = new int[year.size()];
for (int i = 0; i < ints.length; i++)
ints[i] = i;
There is no way I know of in Java to dynamically add variables to a scope. You can use a map as a type of variable... well, mapping instead:
final List<Integer> years = getYearList();
final Map<String, Integer> yearMapping = new HashMap<String, Integer>();
for(int year : years)
{
final String name = generateNameForYear(year);
yearMapping.add(name, new Integer(year));
}
// Later... Get "variables" out of the map:
final String variableName = "fooYear";
if (yearMapping.containsKey(variableName))
{
final Integer variableValue = yearMapping.get(variableName);
}
else
{
// "variable" does not exist.
}

Categories