将数组内容分配给另一个

时间:2018-06-02 18:14:18

标签: java arrays

所以我是Java的新手。

我在练习时遇到了这个问题。

enter image description here

我的解决方案

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.

    }

}

从我的讲义开始就说明了这一点。

在Java中,赋值运算符可用于复制基本数据类型变量,但不能用于复制数组。

enter image description here

但是当我尝试运行上面问题中编写的代码并打印结果时。它给了我完整的随机数输出。

输出

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

以上输出的完整代码。

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

    }

 }


}

我的问题是如何可能的?由于在说明中声明数组内容不能通过在数组之间直接分配来复制。如果我没有弄错的话,这也适用于C.

我的解决方案也是正确的吗?我只想了解这是怎么回事以及为什么会这样?

3 个答案:

答案 0 :(得分:1)

分配数组

values = numbers;

将导致变量values引用数组numbers,即复制引用。

但是,变量values是方法的参数,它即将超出范围。所以分配的参考文件即将被丢弃。 Java严格来说是一种按值传递的语言。将对数组的引用传递给方法时,该引用的值(实际上是指针)将按值传递给方法。因此,在顶部的原始代码中,调用者的数组将保持不变,以及新的随机数组(由指向 valuesnumbers变量完成该方法,但之后没有任何指向)将成为垃圾,将被垃圾收集和丢失。

如果要保留包含随机数的新数组,请从方法中返回。另一方面,如果您希望更新调用者的数组,那么可以将每个项目从numbers复制回values,但是更容易生成values中的随机数开头(然后根本不需要numbers数组):

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

方法的名称fillWithRandomNumbers确实表明后一种操作是调用者想要的,也是预期的。

另见Is Java “pass-by-reference” or “pass-by-value”?

答案 1 :(得分:0)

你没有复制数组。您只是在内存中引用相同的对象。想象一下,如果你有一个数组x= [1 , 2, 3, 4]; 你说y = x; yx都指向内存中的相同空间。因此,如果我更改x中的值,则会更改y中的值。没有副本,而是相同的确切对象。如果我向x添加值,则会反映在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];
}

答案 2 :(得分:0)

你的笔记说:

  

在Java中,赋值运算符可用于复制原始数据类型变量,但不能用于复制数组。

本说明的含义是您无法使用赋值运算符对另一个数组执行深层复制。赋值运算符的作用是对较深的副本进行浅复制。什么是浅拷贝和深拷贝?好吧,所有数据都存在于内存中。当我们创建数组x时,会为其分配一个内存位置,例如0x1000(位置无关紧要)。如果我们采用另一个变量y并为其分配x(y = x),这样做不会复制x中的所有值,它会复制该内存位置{{1 }}。所以现在0x1000x指的是内存中的相同位置。这称为浅拷贝。如果我们更改y x:中的值,(x[3] = 4)也会收到该更改(y // 4!)。 y不是一个独立的副本。当我们复制基元时,我们得到变量代表的值而不是它的内存位置。 例如:

System.out.println(y[3])

如果你想做一个深层复制,你会做这样的事情:

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!

现在,如果您更改数字中的值,则不会更改值中的值。 例如:

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