0

So I'm new to Java.

I encountered this question while doing exercises.

enter image description here

My Solution

public static void fillWithRandomNumbers (double[] values) {

    double[] numbers = new double[values.length];

    for(int i = 0 ; i < numbers.length ; i++){

    numbers[i] = Math.random();
    values[i] = numbers[i];                  // <---- That's the only thing I changed from the above code.

    }

}

Since from my lecture notes it states that.

In Java, the assignment operator may be used to copy primitive data type variables, but not arrays.

enter image description here

But when I tried to run the code written in the question above and print the results. It gives me the full random number output.

Output

--------------------Configuration: Test - JDK version 1.8.0_171 <Default> - <Default>--------------------
0.5879563734452546
0.18409227033985642
0.7866217402158342
0.8023851737037745
8.892207358659476E-4
0.8614310541417136
0.6907363995600082
0.8974247558057734
0.4294464665985942
0.19879131710939557

Process completed.

The Full Code From The Above Output.

public class Test {

   public static void main(String[] args) {

    double[] test = new double[10];

    fillWithRandomNumbers(test);


   }



   public static void fillWithRandomNumbers(double[] values){

    double[] numbers = new double[values.length];

    for(int i = 0 ; i < numbers.length ; i++){

    numbers[i] = Math.random();
    values = numbers;
    System.out.println(values[i]);

    }

 }


}

My Questions is how is that possible? Since in the notes it stated that array contents can't be copied by direct assigning between arrays. This also applies to C if I'm not mistaken.

And also is my solution correct? I just want to understand how and why is this possible?

Cash-
  • 67
  • 1
  • 10
  • Note: snippets are for embedding runnable javascript (and html and css) in questions, not for formatting code blocks. – David Conrad Jun 02 '18 at 18:26

3 Answers3

1

Assigning the array

values = numbers;

will cause the variable values to refer to the array numbers, that is, it copies the reference.

However, the variable values is a parameter to the method, and it is about to go out of scope. So the reference assigned is about to be thrown away. Java is strictly a pass-by-value language. When you pass a reference to an array to a method, the value of that reference (essentially, a pointer) is passed to the method by value. So in the original code at the top, the caller's array will remain unchanged, and the new array of random numbers (pointed to by both the values and numbers variables just prior to completion of the method, but not pointed to by anything after) will become garbage and will be garbage collected and lost.

If you want the new array with the random numbers to be retained, return it from the method. On the other hand, if you want the caller's array to be updated then could could copy each item from numbers back to values, but it would be easier to just generate the random numbers in values to begin with (and then there's no need for the numbers array at all):

for (int i = 0; i < values.length; i++) {
    values[i] = Math.random();
}

The name of the method, fillWithRandomNumbers, really suggests that this latter operation is what is wanted, and expected by the caller.

See also Is Java “pass-by-reference” or “pass-by-value”?

David Conrad
  • 15,432
  • 2
  • 42
  • 54
  • you mean "return it from the method, or assign its items to the items of `values`". – Walter Tross Jun 02 '18 at 18:38
  • If you change the index value of the callers array, it'll be reflected outside the function. – Eddie D Jun 02 '18 at 18:44
  • @WalterTross that's true, you could assign its items to the items of `values`. But then it would be easier to eschew `numbers` altogether and just generate the random numbers into `values` directly. I'll edit to reflect that. – David Conrad Jun 02 '18 at 18:45
  • Thank you for this high quality response. I understand now , as I have forgotten about arrays that passes in a function aka method in java is a pass by reference and it affects/changes the original value outside of the method itself. So there is no need for a temporary aka numbers array. – Cash- Jun 02 '18 at 19:13
0

You're not copying the array. You're merely referencing the same object in memory. Imagine if you have an array x= [1 , 2, 3, 4]; and you say y = x; y and x are both pointing to the same space in memory. So if I change a value in x, it'll change the value in y. There's not a copy, but instead the same exact object. If I add a value to x it'll be reflected in y.

double[] x = new double[10];

double[] y = x;

x[0] = 2.0;

x[0] == y[0] //Will be true

double[] numbers = new double[values.length];

for(int i = 0 ; i < numbers.length ; i++)
{

  numbers[i] = Math.random();
  values[i] = numbers[i];
}
Eddie D
  • 1,120
  • 7
  • 16
  • Thank you for your quick response I appreciate it. Now I understand as I have looked through my notes. So my solution is the proper way copying? [link](https://i.imgur.com/xkeXYdl.png) <-- Note – Cash- Jun 02 '18 at 18:25
  • Anytime. Please mark as answered if this solved your question. Also, posted some more stuff to further explain. – Eddie D Jun 02 '18 at 18:25
  • So my solution is the proper way to copy arrays from one content to another? – Cash- Jun 02 '18 at 18:28
  • Not quite, you're reassigning the first instance of an array. I'll post a correction write now :] – Eddie D Jun 02 '18 at 18:29
  • That should resolve the difference. If you change one array now, it will not change the other :D – Eddie D Jun 02 '18 at 18:41
0

Your notes say:

In Java, the assignment operator may be used to copy primitive data type variables, but not arrays.

What this note means is you cannot do a deep copy of another array with the assignment operator. What the assignment operator does is make a shallow copy versus a deep copy. What are shallow copies and deep copies? Well, all data exists in memory. When we create array x, it is assigned a memory location, say 0x1000 (the location doesn't matter). If we take another variable y and assign it x: (y = x), what this does is not copy over all the values in x, it copies that memory location 0x1000. So now x and y refer to the same place in memory. This is called a shallow copy. If we change a value in x: (x[3] = 4), y receives that change as well (System.out.println(y[3]) // 4!). y is not an independent copy. When we copy primitives we get the value that variable represents and not its memory location. ex:

x = 5;
y = x;
y = 2;
// x equals 5 and y equals 2. changing the value of y did not change the value of x!

If you wanted to do a deep copy you would do something like this:

for(int i=0; i < numbers.length; i++){
    numbers[i] = Math.random();
    values[i] = numbers[i];
}

Now if you change a value in numbers it won't change a value in values. ex:

System.out.println(numbers[0]) // 0.5879563734452546
numbers[0] = 1.2;
System.out.println(values[0]) // 0.5879563734452546
Nemo
  • 2,441
  • 2
  • 29
  • 63