java method to change the value of an array to null - java

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);
}
}

Related

How can I get my binary tree insert function to work?

/ Solved /
I actually passed null. Since it doesn't contain any information, adding values to it won't affect my tree, thanks for the answer!
We have got a task in Java to create a binary tree which can hold integer. We have to write an insert function which inserts an integer to a tree by coincidence. I have now written the function but somehow it doesn't add the values I put in.
My class consists of an integer "value" and two references for the left and right branch, "left" and "right".
Also, I have to write this function in this way, so they have to return void, I am aware that there are easier ways.
So, for now, I already know that I get to the leaf. Then it's t == null. When I try, then to put "t = new CONSTRUCTOR(value, ...)"
it doesn't change anything.
public void insert_in_tree(int i) {
/*Creating random number*/
Random rand = new Random();
int rand_num = rand.nextInt(2);
if(rand_num == 0) {
setLeft(this.left, i);
} else {
setRight(this.right, i);
}
}
... here is the code for the "setLeft" (The "setRight" function is the same, I just pass the right subtree when I am calling it) function:
void setLeft(IntBinTree t, int value) {
if(t == null) {
t = new IntBinTree(value, null, null);
return;
}
int i = 0;
/*Random number*/
Random rand = new Random();
int rand_num = rand.nextInt(2);
/*Calling either left or right*/
if(rand_num == 0) setLeft(t.left, value);
setRight(t.right, value);
}
I suppose, the error is calling the function and changing then the local variable "t" instead of using "this". However, since I am passing a reference of "this", there shouldn't be any problem in doing this, can anyone spot the error?
You are passing a null to a function. NOT an object.
If you passed an object (e.g. "this"), it would pass the reference to that object (in reality, Java is "Pass by value", but what you pass by value is the reference, NOT the object itself) and any changes to it would reflect outside the function.
Passing a null would NOT do that since there is no object reference and you are just passing a value of "null" which has NOTHING to do with your original object, so any changes to "t" made inside the second function are lost.
What you should do is one of 2 things:
Pass "this" and a left/right flag.
Create left/right sub-tree (if empty) in the caller, pass the newly created and assigned subtree.
By the way, you have nearly identical code for left/right in the top level method and in set method - it would be easier to keep it entirely in the set method.

Recursive method for binary tree node couting

Ok, so i have to create a recursive method for counting the nodes in a tree, and i did this (variable names are in portuguese, sorry):
public int contaNos(Arvbin r) {
Integer cardinalidade = 0;
contaNosPrivado(r, cardinalidade);
return cardinalidade;
}
private void contaNosPrivado(Arvbin r, Integer cardinalidade) {
if (r==null) {
return;
}
cardinalidade=cardinalidade+1;
contaNosPrivado(r.esq, cardinalidade);
contaNosPrivado(r.dir, cardinalidade);
return;
}
Arvbin is the binary tree, esq and dir are the left and right references to the tree's branches.
I thought this would work, but for some reason when i try to run it, it returns 0. I've usen a little bit of debugging and i think the issue is that when the methods finish and come back to the original non-recursive one, the cardinalidade variable is set to 0. I'm not sure if it's because autoboxing is messing with my Integer and turning it into an int, and then when i call the method it passes a copy of the value instead of the reference to the existing object, and i don't know how to fix it. If anyone could help, i'd greatly appreciate it
The problem is that wrapper classes are immutable in Java. cardinalidade is just a parameter of contaNosPrivado here and, unfortunately, cannot act as an argument like other object type parameters can, i.e. this local reference cannot change inner fields of the object that initial reference refers. Any change to it affects it only the way it affects any primitive local variable.
What exactly happens inside your contaNosPrivado:
On invocation, it is indeed supplied a reference to an Integer object. This reference is assigned to a local variable named
cardinalidade.
In this line:
cardinalidade=cardinalidade+1;
this object is first unboxed to a primitive int variable, this variable is incremented afterwards, and
finally the result is reboxed into a new Integer object which is
then assigned to cardinalidade. There is no way to 'increment'
original object, even if you use the increment operator:
cardinalidade++;
Any further processing applies to the newly created Integer object and doesn't affect the reference passed to contaNosPrivado.
To achieve your goals, use something like this instead:
static int contaNosPrivado(Arvbin r) {
if (r == null)
return 1;
else
return contaNosPrivado(r.esc) + contaNosPrivado(r.dir);
}
As #John McClane has pointed out, you can't pass an Integer argument by reference, only by value.
But there's also no need for a private helper method, you can just simplify it all to a single method:
public int countLeaves( BinaryTreeNode n )
{
return n == null? 0 : ( countLeaves( n.rightLeaf ) + countLeaves( n.leftLeaf ) );
}
Or (excuse my poor Portugese):
public int contaNos( Arvbin r )
{
return r == null? 0 : ( contaNos( r.esq ) + contaNos( r.dir ) );
}

Java Tree Recursion parameter issues

I am attempting to give a void function to a Tree. It calculates some parameters and uses Ids to reference some coordinates and the distance between them. The problem I have is that every recursion call returns me 0 on both parameters I use, I thought in Java every variable was a reference so this would work, but I seem to be missing something. Here is the code:
public void volumeandcost(Integer volume,Float cost){
if(children().equals(0)){//children() returns the number of children our tree has
volume=volume+getCapacidad(this.root);//root is the Id
}
else{//recursive call
ArrayList<Integer> myvol= new ArrayList();
ArrayList<Float> mycost=new ArrayList();
for(int i=0;i<this.children();i++){
myvol.add(new Integer(0));
mycost.add(new Float(0.0));
children.get(i).volumeandcost(myvol.get(i), mycost.get(i));
cost=cost+mycost.get(i)+myvol.get(i)*
square(ProbIA5Board.m_dist.get(this.root).get(this.children.get(i).getId()));
}
//this calculates our volume in case we have children
volume=min(getCapacidad(root)*3,mysum(myvol)+getCapacidad(root));
}
}
I call this function with both parameters initially set at 0, and they come back in the same way after the call to volumeandcost.
After following some advice I implemented a new class Pair like this:
public class Pair {
Integer vol;Float cost;
public Pair (){this.vol=new Integer(0);this.cost=new Float(0);}
Integer getVol(){ return this.vol;}
Float getCost(){ return this.cost;}
void setVol(Integer x){this.vol=x ;}
void setCost(Float x){this.cost=x ;}
void addVol(Integer x){this.vol=this.vol+x;}
void addCost(Float x){this.cost=this.cost+x;}
}
and modified the function so that it's like this:
public void volumeandcostp(Pair p){
if(children().equals(0)){
p.setVol(p.getVol() + getCapacidad(this.root));//tenemos el volumen
}
else{//recursion
ArrayList<Pair> myvol= new ArrayList();
for(int i=0;i<this.children();i++){
myvol.add(new Pair());
children.get(i).volumeandcostp(myvol.get(i));
myvol.get(i).getCost());
p.addCost(myvol.get(i).getCost()+ myvol.get(i).getVol()* square(ProbIA5Board.m_dist.get(this.root).get(this.children.get(i).getId())));
} p.setVol(min(getCapacidad(root)*3,mysump(myvol)+getCapacidad(root)));
}
}
But all the getters from Pair keep giving me 0 as answer.
I thought in Java every variable was a reference.
First of all that statement is wrong: you have primitive types like int, float, char. Those are not references to begin with. But indeed variables with types other than those eight are references.
But when you call a function, Java does a call-by-value. That means the references are copied. When you call: volumeandcost(a,b). Java will make a copy of the reference. So volume and cost work independently. Setting them (i.e. assigning a new value to them) in your method has no effect.
You can alter the state of the objects you are given: since you copy the reference a refers to the same object as volume (in the example above), you can call methods on the objects the references refer to and alter the state, but you cannot change the reference itself.
As provided in other answers, you can only alter the state of the objects when you pass them to a method- Java is call by value.
Consider this instead of Integers :
List<Integer> list = new ArrayList<Integer>();
System.out.println( "Before adding size is " + list.size() );
modifyList(list);
System.out.println( "After adding size is " + list.size() );
public void modifyList( List<Integer> list )
{
list.add( 5 );
}
Why do you see the list.size() modified ? Because list's state is modified not the original reference to list itself, the copied reference that passed to method played with a method called add and modified the state of object it refers to. So when you call size() using original reference , you will get the updated state of the object.
Now, to tackle your problem, you could do it with devising your own class, some thing like :
class Metrics
{
Integer volume;
Float cost;
}
Pass Metrics to your new method and update the fields volume, cost inside your method.

Array reference type in a method

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(); );

In Java, Is it possible to concatenate the value of a variable into a variable name (Sounds messed up, but please read details)

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.
}
}

Categories