Array of static objects get the same value after cicle - java

I'm testing the result of this code, to realise how the static object creating works.
Basically i understood everything till the last System.out.println(" " + a[0]); I ran the debugger, and i verified that in that point, all of the elements of the array have the same value on num variable.
Can anyone explain me why is it happen?
static class Numero {
private static int sn = 0;
private int num;
public Numero(int n) {
num = n;
++sn;
}
public void setNum(int n) {
num = n;
}
public String toString() {
return "num = " + num + " sn = " + sn;
}
}
public static void main(String[] args) {
Numero[] a = new Numero[3];
Numero x = new Numero(12);
for (int i = 0; i < a.length; i++) {
a[i] = x;
a[i].setNum(i);
System.out.println(" " + a[i]);
}
System.out.println(" " + a[0]);
}
Output:
num = 0 sn = 1
num = 1 sn = 1
num = 2 sn = 1
num = 2 sn = 1

This is because your Numero object is mutable. When you modify it in any way, all references to it are modified as well.
When you call a[i] = x:
You don't create a copy of x and put it in position i.
You do store a reference to x at position i.
So, by the end of your iteration, your array has stored three references to the same object (you can think of it as {x, x, x}). And since that object has changed throughout the loop (because a[i].setNum(i) is equivalent to x.setNum(i)), your last output prints the num value as 2.

You created a single Numero, so sn got incremented once, to 1. That same instance got assigned to each element of a; you saw different values for num because you printed it out at different times.

Making a static class essentially enforces the singleton design pattern. The class can only have static methods and static instance fields. Static instance fields hold the same value across all instances of the class, and you can think of it as all objects of that class sharing the same variable instead of having copies of it.
When you print a[0] in the loop, you get what you expect, but after the loop, that static ("shared") variable was changed by other objects, leaving num to be the value of 2, set by the last iteration of the for loop.

issue lies here
a[i] = x;
a[i] is pointing to X now , so whenever you call setNum method ,method belongs to X .so you will get same instance output always

Related

Array Recursion Excercise

a) Create an array of random numbers, whose size is a power of 2. Using loops, find the difference for each pair of values (index 0 & 1, 2 & 3, 4 & 5 etc.) and store them in a new array. Then find the difference for each pair of differences and so on until you have only one difference left.
Hint: Think carefully about your loop bounds
b) Now, create a solution that is 'in place', i.e., It does not require the creation of new arrays. Again, this will require careful consideration of loop bounds.
c) Finally, write a solution that makes use of a recursive function, instead of loops.
I have been trying to solve the above exercise but I am stuck with what b means and how can I use recursive function. The following is my solution for part a :
public class RandomArray{
private static double ArrayFn(int p){
double[] orignalArray = new double[(int)Math.pow(2,p)];
for (int i = 0; i< orignalArray.length; i++){
orignalArray[i] = (int)(Math.random() * 10) ;
}
System.out.println(Arrays.toString(orignalArray));
double y = ArrayDifferenceloop(orignalArray);
System.out.println("Value of Array" + y);
return y;
}
private static double ArrayDifferenceloop(double[] arg){
do{
double[] newArr = new double[(arg.length/2)];
for (int i = 0; i< arg.length; i+=2){
newArr[i/2] = arg[i] - arg[i+1];
}
System.out.println("New Array is =" + Arrays.toString(newArr));
//copy newArr to arg
arg = new double[(newArr.length)];
System.arraycopy(newArr,0,arg,0,newArr.length);
}while(arg.length > 1);
return arg[0];
}
public static void main(String[] args){
double z = ArrayFn(3);
System.out.println("value" + z);
}
}
I can help you with point b)
you can store the differences in the original array itself:
difference of [0] and [1] put in [0],
difference of [2] and [3] put in [1],
and so on.
You can calculate the index to put the result from the indexes of the pair or keep two index variables for the result and for picking the pairs.
you just keep iterate over the original array repeatedly, each time over fewer cells until only two cells left.
the recursive solution should be clear...
I guess option b means use the original array to store the differences, rather than creating a new array.
This can be achieved by dynamically changing the active range of elements used, ignoring others (see also Sharon Ben Asher answer ):
private static double ArrayDifferenceloop(double[] array){
int activeLength = array.length;
do{
int index =0; //index where to store difference
for (int i = 0; i< activeLength; i+=2){
array[index++] = array[i] - array[i+1];
}
System.out.println("Modified array (only "+index+ " elements are significant) " + Arrays.toString(array));
activeLength /=2;
}while(activeLength > 1);
return array[0];
}
/* Solution for part (b) hope it works for you*/
public class RandomArray{
static int len; /*modification*/
private static double ArrayFn(int p){
double[] orignalArray = new double[(int)Math.pow(2,p)];
len=(int)Math.pow(2,p);
for (int i = 0; i< orignalArray.length; i++){
orignalArray[i] = (int)(Math.random() * 10) ;
}
System.out.println(Arrays.toString(orignalArray));
double y = ArrayDifferenceloop(orignalArray);
System.out.println("Value of Array" + y);
return y;
}
private static double ArrayDifferenceloop(double[] arg){
do{
for (int i = 0; i< len; i+=2){ /*modification*/
arg[i/2] = arg[i] - arg[i+1];
}
//copy newArr to arg
//arg = new double[(arg.length)];
len=len/2; /*modification*/
System.out.print("new Array : ");
for(int i=0;i<len;i++){
System.out.print(arg[i]+" , ");
}
// System.arraycopy(arg,0,arg,0,len);
}while(len > 1);
return arg[0];
}
public static void main(String[] args){
double z = ArrayFn(3);
//System.out.println(Arrays.toString(orignalArray));
System.out.println("value" + z);
}
}

Arithmetic operation on primitive class variables [duplicate]

This question already has answers here:
Uninitialized variables and members in Java
(7 answers)
Closed 5 years ago.
Couldn't find an explicit description of what's happening so thought i'd bring this up to the community.
public class Temp {
static int i;
int j;
int sum = i+j;
}
public class Main{
public static void main(String[] args){
Temp obj = new Temp();
obj.i = 1;
obj.j = 2;
System.out.println(obj.sum); //returns '0'
}}
Is it because both integers i and j were empty during instantiation that the 'sum' variable is empty?
Thanks in advance!
Temp obj = new Temp(); // creates an instance of object type Temp
Here, data members, i, j, and sum are initialized to 0
obj.i = 1; // assigns value of Temp data member, i to 1
obj.j = 2; // assigns value of Temp data member, j to 2
Note that the value of data member sum of Temp Object obj is still 0.
To make, sum = i + j, you need to initialize it to i + j when i and j are initialized.
Simply write obj.setSum() method to set the value of sum and obj.getSum() after that to retrive the updated value of it.
public class Temp {
static int i;
int j;
int sum = i+j;
public void setSum(){
sum = i + j;
}
public int getSum(){
return sum;
}
}
public class Main{
public static void main(String[] args){
Temp obj = new Temp();
obj.i = 1;
obj.j = 2;
obj.setSum();
System.out.println(obj.sum); //OR obj.getSum()
}
}
Is it because both integers i and j were empty during instantiation
that the 'sum' variable is empty?
Yes, i+j is assigned to 'sum' when the Object is instantiated. By default java assign 0 to int values when you don't assign a value.
You need to update the sum variable by directly assigning the value to it.
obj.i = 1;
obj.j = 2;
obj.sum = obj.i + obj.j.
A workaround is to create a getter method in your Temp class instead of the variable sum:
public class Temp {
static int i;
int j;
public int getSum() {
return i + j;
}
}
Then to print the sum :
System.out.println(obj.getSum());
When you create another class that will be use by the main method
numeric data fields are set to zero
Character fields are set to Unicode \u0000
Boolean fields are set to false
Fields that are object references are set to null or (empty) for example String data fields

java: how to calculate multiplication between all values in variable difference

I received that task:
"A small method, calculateProduct is to be written. It will ask the user to enter two int values, and then calculate and display the product of all the values between the two values entered. For example if the user enters the numbers 2 and 5 the program will display the result 120 (calculated as 2 * 3 * 4 * 5)"
I tried to build something like this:
import java.util.Scanner;
public class Exam {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int a;
int b;
int big;
int small;
//ask to insert two variables
System.out.println("Insert variable a");
a = in.nextInt();
System.out.println ("Insert variable b");
b=in.nextInt();
// compare two variables
// set the biggest variables to b, the smallest - to a
if (a >=b){
big=a;
small=b;
}
else {
big=b;
small=a;
}
// set the do while loop to complete the code. Run multiplying before counter won't fit to b variable
int result = small;
for (int i=small; i<=big;i++){
result*=i;
}
System.out.println("the multiplication progression between "+small+" and "+big+" equals to "+result);
}
}
However, when I insert 2 and 5 the result is 240. Does anybody know how to fix it? thanks!
Change loop to:
for (int i = small + 1; i <= big; i++)
{
result *= i;
}
you init result with small then multiply it by small again.
Fix: Start the for statement with small+1
...
int result = small;
for (int i=small+1; i<=big;i++){
result*=i;
}
....
The other obvious solution here is to change the init statement from
int result = small;
to
int result = 1;
In that case you don't have to touch your looping code.
And for the record: "small" is a rather bad name here, why not call it "smallerInput" or something like that.
Finally: you could avoid dealing with "small" - if a < b you can simply loop from a to b; and otherwise you could loop "backwards" from "b to a".
Just change your for loop as below mentioned will solve your problem.
The problem in your loop is :
In its first iteration it is multiple with itself rather than its
incremented value.
From:
for (int i=small; i<=big;i++)
To:
for (int i=small+1; i<=big;i++)
The task is to write a method called "calculateProduct". Above you are doing all your callculation in your main method. Try to separate that. Example :
import java.util.Scanner;
public class Exam {
public static void main (String[]args) {
Scanner in = new Scanner(System.in);
int a;
int b;
System.out.println("Insert variable a");
a = in.nextInt();
System.out.println ("Insert variable b");
b=in.nextInt();
if(a>=b){
calculateProduct(b,a);
}
else{
calculateProduct(a,b);
}
}
public static void calculateProduct (int m, int n) {
int result = 1;
for (int i = m; i <= n; i++) {
result *= i;
}
System.out.println("the multiplication progression between "+m+" and "+n+" equals to "+result);
}
}

Java - variable in method not erased after call

I really need to explain behavior of code I have created.
Variable preyPred here: private static double[] preyPredLV(double[] preyPred, double[] a, double[] b, int n) is local for method preyPredLV or not?
Because, when I manipulate it during calling of the method, and then I call the method again for different n, it does not assign preyPredDefault as value of preyPred, but it uses its own value from previous call. Shouldn't its previous value be discarded when method returns output value and shouldn't be the new value assigned during next call? Can someone please explain? Thank you
Whole code:
public class Main {
public static void main(String[] args) {
double[] preyPredDefault = {300, 20};
double[] a = {0.1, 0.01};
double[] b = {0.01, 0.00002};
int n = 1;
double[] result = preyPredLV(preyPredDefault, a, b, n);
System.out.println("After "+n+" generations: Hares = "+result[0]+" and Lynx = "+result[1]);
n = 2;
result = preyPredLV(preyPredDefault, a, b, n);
System.out.println("After "+n+" generations: Hares = "+result[0]+" and Lynx = "+result[1]);
}
private static double[] preyPredLV(double[] preyPred, double[] a, double[] b, int n) {
double[] preyPredOld = new double[2];
System.out.println("n = "+n);
System.out.println("preyPred[0] = "+preyPred[0]);
System.out.println("preyPred[1] = "+preyPred[1]);
for(int iteration = 0; iteration < n; iteration++){
preyPredOld[0] = preyPred[0];
preyPredOld[1] = preyPred[1];
preyPred[0] = preyPredOld[0] * (1 + a[0] - a[1]*preyPredOld[1]);
preyPred[1] = preyPredOld[1] * (1 - b[0] + b[1]*preyPredOld[0]);
}
return preyPred;
}
}
Result:
n = 1
preyPred[0] = 300.0
preyPred[1] = 20.0
After 1 generations: Hares = 270.00000000000006 and Lynx = 19.92
n = 2
preyPred[0] = 270.00000000000006
preyPred[1] = 19.92
After 2 generations: Hares = 219.31183648512007 and Lynx = 19.726535847029762
Arrays in Java are not passed as a copy. They are passed as a reference to the array, which is then shared between caller and method.
So if you update the array from within the method, this is an in-place update, and the changes will be visible to whoever else has a reference to that array.
If you want to avoid that, make a "defensive copy" (using Arrays.copyOf) and make changes only to that.
You are passing a reference of the preyPredDefault array to your preyPredLV method, and your method updates this array via the reference you pass. Thus your method modifies the content of that array.
If you don't want preyPredLV to update that array, you can pass it a copy of the array.
double[] result = preyPredLV(Arrays.copyOf(preyPredDefault,preyPredDefault.length), a, b, n);

java reverse a string of numbers

I need to be able to input a list of numbers the last being -1 and have it print the reverse(not including -1) and then find the average. I have to use a function for finding the reverse. Im stuck because it cannot resolve my average which means I cannot run the program to see if there are other problems.
import java.util.Scanner;
public class Reverse {
public static void inReverse (int a) {
int number;
int[] value;
for (a = number - 2; a >= 0; a--) {
System.out.print(value[a] + " ");
}
}
public static double findAverage (int p, double average) {
int number;
for (p = number - 2; p >= 0; p--) {
average += value[p];
}
average = average / (number - 1);
return average;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int[] value;
int i, number, size;
size = 20;
System.out.println("Please enter the integers: ");
while (value[i - 1] != -1 && number < size) {
value[i] = input.nextInt();
i += 1;
number = i;
}
System.out.println("The values in reverse order are: ");
inReverse(i);
System.out.println(" ");
System.out.println("The average is " + average);
}
}
Your problem is that you have confused "local variables" with "fields".
Local variables are variables that you declare inside the body of a method. They can't be used before the declaration, and they can't be used once the method stops running - their values have ceased to exist.
Fields are variables that you declare inside your class, but outside any methods. These live inside each object of the class (or inside the class itself if you declare them as static), which means they keep their values from one method call to the next.
You have int number; and int[] value; declared inside different methods, which means they are local variables, and they are recreated each time those methods run. This isn't what you want. You either want to pass them from one method to the next, as parameters; or to have them as fields of your class.

Categories

Resources