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.
Related
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.
I have the following:
ArrayList<int[]> lista = new ArrayList<int[]>();
int[] posible_mov = new int[2];
posible_mov[0] = 0;
posible_mov[1] = 0;
lista.add(posible_mov);
posible_mov[0] = 1;
posible_mov[1] = 1;
lista.add(posible_mov);
Well, if I walk the show with arraylist and get all elements method, shows me in both cases:
lista.get(0) => 1, 1
lista.get(1) => 1, 1
WHY?
You adding a reference to the posible_mov into the lista. That's why you always print 1,1 because in the last part of the code you are assigning posible_movthe value 1. You can try to change the order of the assignments and you will see you will print 0,0 instead.
If you want to add several objects, and not reference them, then you can do:
int[] posible_mov = new int[2];
posible_mov[0] = 0;
posible_mov[1] = 0;
lista.add(posible_mov);
posible_mov = new int[2]
posible_mov[0] = 1;
posible_mov[1] = 1;
lista.add(posible_mov);
For further reading check Java Pass by reference or value
Your reference variable just override the previous stored values.
So in order to not let that happen, you can create another objects without referencing them or create an another array with a different name if you want to retain both the arrays simultaneously.
After the first lista.add() function, you can add one of the below:
posible_mov = new int[2];
or
int[] posible_mov_1 = new int[2]; //Use this variable name for further operations on this object
I am writing a code where i have to add a 1d array in 2d array.
For example: I have a userlist array which will add data array in it
Double[][] userList = new Double[4][appName.size()];
Double[] data = new Double[appName.size()];
so user list will have something like this:
userlist={{1,2,3,4}, {2,3,4,7}, {0,0,1,2,}}
where {1,2,3,4}===> represents data array.
Problem: The problem that i am getting is that each time what data array returns just overwrite the whole thing in userlist with the new data.
for example:
if userlist={{1,2,3,4}, {2,3,4,7}} and data returns {0,0,4,5}
then my userlist becomes: {{0,0,4,5}, {0,0,4,5}, {0,0,4,5} }.
Code:
Double[][] userList = null;
userList = new Double[4][appName.size()];
String prevName = null;
Double[] data = new Double[appName.size()];
int count=0;
for(AuditInformationEntity e : auditInfoList)
{
//int count =0;
if(prevName== null || !prevName.equals(e.getDisplayName()) )
{
if(prevName!=null)
{
////====>> I think Something to be done here<========/////
userList[count++]=data;
}
//data = new ArrayList<Double>();
for(int i = 0 ; i<appName.size();i++)
data[i]=0d;
prevName = e.getDisplayName();
}
Double d = data[appName.indexOf(e.getAppName())];
if(d==null){
d=1d;
data[appName.indexOf(e.getAppName())]= d;
}
else
{
d++;
data[appName.indexOf(e.getAppName())]= d;
}
}
userList[count++]=data;
return userList;
You've correctly identified the problem line. Java doesn't technically have multidimensional arrays; instead, it has arrays of arrays. This means that when you say userList[i] = data, you're just telling Java to update the reference of userList[i] to point to the same data array. (This is called an aliasing bug, since you are thinking you're dealing with different arrays, but you're just calling the same array by different names.)
Instead, in this case it's probably better to do this:
int i;
double userList[][] = new double[numberOfArrays][];
double data[] = new double[4];
...
// inside a loop
// read into data
userList[i] = Arrays.copyOf(data);
This doesn't actually allocate the inside 4-element arrays when you create userList; it makes copies of each version of the data array when you're adding it.
I need to create an Arraylist in a while loop with a name based on variables also in the loop. Here's what I have:
while(myScanner.hasNextInt()){
int truster = myScanner.nextInt();
int trustee = myScanner.nextInt();
int i = 1;
String j = Integer.toString(i);
String listname = truster + j;
if(listname.isEmpty()) {
ArrayList listname = new ArrayList();
} else {}
listname.add(truster);
i++;
}
The variable truster will show up more than once while being scanned, so the if statement is attempting to check if the arraylist already exists. I think I might have done that out of order, though.
Thanks for your help!
Store the ArrayLists in a Map:
Map<String, List<String> listMap = new HashMap<String,List<String>>();
while (myScanner.hasNextInt()){
// Stuff
List<String> list = new ArrayList<String>();
list.add(truster);
listMap.put(listname, list);
}
Note the use of generics (the bits in <>) to define the type of Object the List and Map can contain.
You can access the values stored in the Map using listMap.get(listname);
If I understand you correctly, create a list of lists or, better yet, create a map in which the key is the dynamic name you want and the value is the newly created list. Wrap this in another method and call it like createNewList("name").
Really not sure what you mean at all but you have some serious fundamental flaws with your code so I'll address those.
//We can define variables outside a while loop
//and use those inside the loop so lets do that
Map trusterMap = new HashMap<String,ArrayList<String>>();
//i is not a "good" variable name,
//since it doesn't explain it's purpose
Int count = 0;
while(myScanner.hasNextInt()) {
//Get the truster and trustee
Int truster = myScanner.nextInt();
Int trustee = myScanner.nextInt();
//Originally you had:
// String listname = truster + i;
//I assume you meant something else here
//since the listname variable is already used
//Add the truster concated with the count to the array
//Note: when using + if the left element is a string
//then the right element will get autoboxed to a string
//Having read your comments using a HashMap is the best way to do this.
ArrayList<String> listname = new ArrayList<String>();
listname.add(truster);
trusterMap.put(truster + count, listname);
i++;
}
Further, you are storing in myScanner a stream of Ints that will get fed in to the array, but which each have very different meanings (truster and trustee). Are you trying to read these in from a file, or user input? There are better ways of handling this and if you comment below with what you mean I'll update with a suggested solution.
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.
}