The error message pertains to this line of code
Player a = pl.get(i);
/*
* CODE MODIFTYING VARIABLES WITHIN THE OBJECT a
*/
pl.get(i) = a;
'pl' is an ArrayList of the class Player
this code is in a for loop where 'i' is equal to the number of intervals the for loop has gone through
it specifies that "(i)" is a variable an it should be a value, what does it mean by value???
Basically, I'm copying my Player object in my array list and setting it to a Player object variable that is created within the for loop and changing the values within the object and then setting the newly created object (Player a) to my index in the ArrayList (pl.get(i))
I'm doing this so I don't have to keep writing pl.get(i).getFunction() pl.get(i).setFunction() pl.get(i).CalculateFunction() pl.get(i).blablabla();
I can just use a.whatever = 83465;
So the question is, what am I missing?
pl.get(i) is a value type (rvalue) and can not be assigned a new value.
Only lvalues can be assigned values.
You have to use the set method of ArrayList to overwrite values in the list:
pl.set(i, a);
Additionally, when calling pl.get(i) to retrieve the element you named a, you can use this reference to change a in any way you want. you don't have to write the object back into the list, as the reference is still there.
Related
Is there any way to check if an array has already been set to a length in Java?
In my case, I have a recursive method, and in the first iteration of the method, I want the array to have the length of a variable n. However, after the first recursion of the method, I don't want the array to be reassigned a new size.
Additionally, I don't know what the size should be until the first iteration of the method.
Thanks!
The array variable would be null until you assign an instance to it. Once an instance is assigned, it will have a fixed length. Therefore, a simple null check would suffice.
The Array Reference Variable Would be NULL until you assign to it.
You cannot create an Array Object without a lenght; if you want that, maybe you should create a ArrayList, and you can add objects to it without care about the size.
If you just want to see the lenght of your Array; after CREATE, do this:
public static void main (String[] args){
String[] x = new String[2]; // you cannot create here without a lenght, you MUST set
System.out.println(x.length);
}
OUTPUT: 2
I have this code. But I don't know how to explain the result:
ArrayList<String> first = new ArrayList<String>();
first.add("1");
first.add("2");
first.add("3");
ArrayList<String> second = new ArrayList<String>();
second = first;
System.out.println("before modified:"+second.size());
second.clear();
System.out.println("after modified:");
System.out.println(" First:"+first.size());
System.out.println(" Second:"+second.size());
The result will be: 3 / 0 /0
The problem I don't know is: when you assign first = second; so, both first and second array will point to same object (1,2 and 3). after you clear all elements on second array, so all reference between second array and these objects will loose (no problem here).
The thing I don't know is: but these objects (1,2 and 3) still hold reference to first array. Why first array's size is 0.
Please explain for me.
Thanks :)
By assigning second = first, there is only one arraylist with two references. The references are the same. So, when call clear using one of the two references (first or second), clear will be performed on the referenced arraylist.
This is something else than you first thought. It's not so that assigning the second = first all the references of the strings you added to the first one, will be copied into a new ArrayList object, that would be magic (in Java).
When you do first = second your ArrayList items will point to the same memory locations. Doing a .clear will remove the elements to which the ArrayList is pointing to. This will have repercussions on the other ArrayList.
If you just want to copy the elements of ArrayList1 to ArrayList2, you could do something like so: ArrayList<String> second = new ArrayList<String>(first);
but these objects (1,2 and 3) still hold reference to first array.
Why first array's size is 0.
ArrayList<String> second = new ArrayList<String>();
second = first;
is the same as writing
ArrayList<String> second = first;
You have made second reference point to the first arraylist,it is not using a new arraylist. So when you call clear it clears the "first" arraylist created - you have two references pointing to one arraylist.
When you assign one ArrayList to two variable and modify any one of them, this will reflect in both.So operation performed in any of one variable also reflect in second one. (Single object referenced by two variable).
In Java a variable (except primitives) is always a reference (which has the start address of object) to an object only, Reference is never an object in itself.
For example
second = first;
is assigning a reference, so that first and second now refering to the same object. Objects are not copied, neither in assignments, nor in argument passing (what is copied/assigned is the reference).
I have an ArrayList that I am adding objects to. Objects are added by using a textbox.
The problem I have is when user enters a value into the textbox, all the entries in my ArrayList take on the new value.
if(e.getSource() == textbox){
String name = textbox.getText();
NameSurferEntry entry = new NameSurferEntry();
entry = db.findEntry(name);
graph.addEntry(entry);
graph.update();
textbox.setText("");
}
Code to add entry:
public void addEntry(NameSurferEntry entry) {
entryArray.add(entry);
}
You're creating a new NameSurferEntry which you on the next line overwrite with a value from your database. If the returned entry is always the same your arraylist will only contain references to the same object.
NameSurferEntry entry = new NameSurferEntry();
entry = db.findEntry(name);
What you should consider is trying to achieve immutability in your objects and/or perform defensive copying. For simple properties it's enough to declare them final, but for complex elements you would typically need to copy the object by creating it anew.
The following sample should work for you, given that you implement the copy constructor
NameSurferEntry copy = new NameSurferEntry(db.findEntry(name));
This means that db.findEntry always returns the same NameSurferEntry instance, and just replaces the name inside it with the name it receives as argument.
Adding an object to an list only adds a reference to the object in the list. It doesn't clone the object to store a copy of it in the list.
BTW, why are you creating a new NameSurferEntry and assign it to the entry variable if it's just to overwrite it with the result of db.findEntry afterwards?
Whatever this is:
entry = db.findEntry(name);
contains and returns one object, and you're changing whatever it contains.
To be more clear: You're adding the same reference to your list over and over, and changing the contents of the single object that reference points at.
This question already has answers here:
Are arrays passed by value or passed by reference in Java? [duplicate]
(7 answers)
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed last month.
When I write like this:
public class test {
void mainx()
{
int fyeah[] = {2, 3, 4};
smth(fyeah);
System.out.println("x"+fyeah[0]);
}
void smth(int[] fyeah)
{
fyeah[0] = 22;
}
}
It prints x22;
When I write like this:
public class test {
void mainx()
{
int fyeah = 5;
smth(fyeah);
System.out.println("x"+fyeah);
}
void smth(int fyeah)
{
fyeah = 22;
}
}
It doesn't print x22, but prints x5.
Why, in the second version function, doesn't the value change? Does it change values only for array elements?
The fyeah variable in your first example contains a reference to an array (not an array), while the fyeah integer in your second example contains an integer.
Since Java passes everything by value the following will happen:
In the array case: A copy of the array reference will be sent, and the original array will be changed.
In the int case: A copy of the integer will be changed, and the original integer will not be changed.
It's because your int is a primitive and the method smth creates a local copy which is why it doesn't print the way you want. Objects are passed by value as well, but a value to the pointer in memory. So when it is changed, the pointer stays throughout both methods and you see the change. Read More Here
Ok. An int in java ( and really all languages that have strict data typing ) is a primitive data type. Its just a single variable of that data type. In java this means its passed by value to the method. So when you pass in the argument, a copy of the passed variable is created. Any operations that take place in the method act on that copy not the passed variable.
Actually in java EVERYTHING is passed by value but getting into the details of how that actually is true with what I am going to say next seems inadvisable.
With the array...its a collection of variables of the primitive data type int. So an entire copy of the array isn't actually made just a copy of the reference to the memory that stores the array. so yes the value of the int IN the array is changed from operations in the method.
In short methods don't change the external value of primitives (int,float,double,long,char) with the operations in the method, you have to return the resulting value of those operations to the caller if you wish to obtain it. Operations do change the value with most objects as well as with arrays of primitives. Hope that helps. Really unsure of how low level to get. Maybe someone else can clearly explain exactly why its by value. I "get" it but find it hard to help other people understand.
Think it in terms of memory: Lets analyse your first program -
In mainx , fyeah is an array of ints , so its a reference ( or a pointer if I may ). This reference points to a location in heap memory where the actual array of ints is stored. Lets say at address 100. Located contiguously from here are three ints ( lets say beginning at address 100 , 104 and 108 respectively are 2 ,3 and 4 ).
Now you call your method smth and pass the reference. Within the method , there is another reference ( of an int array type ) named fyeah. This fyeah is quite distinct from fyeah reference in the mainx method. Now , when you call smth and pass the fyeah from mainx , the fyeah within the smth method is initialized to point to the same location ( ie memory address 100 )
When you access the 0 element of fyeah and assign it a value of 22 , it reaches out to the memory location of 100 and writes this value 22 there. When you come back in your mainx method , the fyeah reference is still referring to memory address 100. But the value present at that location is now 22. So you get that value when you access the first element from fyeah in mainx.
Now , your second program. Your mainx method declares an int ( not an array , but a simple int ) and set it to 5. This fyeah variable is created on stack not on the heap. The value of 5 is stored on the stack. Now you call smth and pass this variable. Within the method smth , you again declare an int variable , fyeah by name ( as a formal method argument ). Again this is distinct from the fyeah of the mainx method and this fyeah is also created on stack.This variable will be initialized to a value of 5, copied over from the fyeah you passed to smth as argument. Note now that there are two distinct copies on fyeah variables , both on stack , and both a value of 5. Now you assign the fyeah in smth a value of 22. This will not affect the fyeah of the mainx method,so when you return to mainx and access fyeah , you see 5.
The int is a value type so 5 is passed directly into smth which can only modify the local copy. An array on the other hand is a reference type so the elements of that array can be modified.
Seeing it a bit less technically, I would say that
fyeah[0] = 22;
is changing the content of (the object pointed to by) fyeah, while
fyeah = 22;
is changing (the variable) fyeah itself.
Another example:
void smth(Person person) {
person.setAge(22);
}
is changing (the content of) the person while
void smth(Person person) {
person = otherPerson;
}
is changing the variable person - the original instance of Person is still unchanged (and, since Java is pass-by-value, the variable in the calling code is not changed by this method)
Hey people i have this structure for the search tree
class State
{
//CLASS STATE
int value;
char[][] state; //the game Grid
State child[]; // children of current state, maximum is 8
State(char[][] src)
{
state=src;
child=new State[8];
}
this is the root node definition
State rootNode = new State(currentGrid);
rootNode.value=-1;
int v =maxValue(rootNode,depth);
after the end of recursion in the max value function the array in rootNode should not be edited since its the the first state but when i Display it i get an array filled with stuff which means that the rootNode.state passed by reference to the max value function :(
//i am trying to implement MiniMax Algorithm.
If you don't want objects that are passed as parameters to be changed, pass in a copy (or make a copy of the parameter inside the method).
Note that char[][] means you have an array of char arrays, i.e. you are working with objects and if you copy the first level you still might have a reference to the second.
Thus you might have to loop through the first level/dimension and copy all the arrays in there, like this:
char target[][] = new char[state.length][0];
for( int i = 0; i < state.length; ++i ) {
target[i] = Arrays.copyOf(state[i], state[i].length);
}
If you need, you can easily create a copy of the array through Arrays.copyOf
You can also create a deep copy. How to do this has been answered here: How to deep copy an irregular 2D array
Yes, Java passes references to arrays and not the array as a value. So if you give a reference to your internal state away, the receiver can change it and the change is "visible" in the source (in fact: it's only one array that has been changed and all reference holders will see the change).
Quick fix/solution: clone your state array and pass a reference to this clone instead of the original. This will keep your internal root state unmodified.