所以我是Java的新手。
我在练习时遇到了这个问题。
我的解决方案
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中,赋值运算符可用于复制基本数据类型变量,但不能用于复制数组。
但是当我尝试运行上面问题中编写的代码并打印结果时。它给了我完整的随机数输出。
输出
--------------------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.
我的解决方案也是正确的吗?我只想了解这是怎么回事以及为什么会这样?
答案 0 :(得分:1)
分配数组
values = numbers;
将导致变量values
引用数组numbers
,即复制引用。
但是,变量values
是方法的参数,它即将超出范围。所以分配的参考文件即将被丢弃。 Java严格来说是一种按值传递的语言。将对数组的引用传递给方法时,该引用的值(实际上是指针)将按值传递给方法。因此,在顶部的原始代码中,调用者的数组将保持不变,以及新的随机数组(由指向 values
和numbers
变量完成该方法,但之后没有任何指向)将成为垃圾,将被垃圾收集和丢失。
如果要保留包含随机数的新数组,请从方法中返回。另一方面,如果您希望更新调用者的数组,那么可以将每个项目从numbers
复制回values
,但是更容易生成values
中的随机数开头(然后根本不需要numbers
数组):
for (int i = 0; i < values.length; i++) {
values[i] = Math.random();
}
方法的名称fillWithRandomNumbers
确实表明后一种操作是调用者想要的,也是预期的。
答案 1 :(得分:0)
你没有复制数组。您只是在内存中引用相同的对象。想象一下,如果你有一个数组x= [1 , 2, 3, 4];
你说y = x
;
y
和x
都指向内存中的相同空间。因此,如果我更改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 }}。所以现在0x1000
和x
指的是内存中的相同位置。这称为浅拷贝。如果我们更改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];
}