Java 为什么在方法中引入新数组?为什么不重用参数?
在方法Java 为什么在方法中引入新数组?为什么不重用参数?,java,Java,在方法normalize中,我输入一个数组,比如说,{1,2,3,4},返回的是一个规范化数组,{0.1,0.2,0.3,0.4}。 我知道我应该在方法中引入一个新数组(b,在下面),但实际上为什么呢 public static double[] normalize(double[] a) { double[] b = new double[a.length]; double sum = 0; for (int i = 0; i < b.length; i+
normalize
中,我输入一个数组,比如说,{1,2,3,4}
,返回的是一个规范化数组,{0.1,0.2,0.3,0.4}
。
我知道我应该在方法中引入一个新数组(b
,在下面),但实际上为什么呢
public static double[] normalize(double[] a) {
double[] b = new double[a.length];
double sum = 0;
for (int i = 0; i < b.length; i++) {
sum += a[i];
}
for (int i = 0; i < b.length; i++) {
b[i] = a[i]/sum;
}
return b;
}
Input: 1 2 3 4
Output: 0.1 0.2 0.3 0.4
publicstaticdouble[]normalize(double[]a){
double[]b=新的双精度[a.长度];
双和=0;
for(int i=0;i
为什么以下是错误的:
public static double[] normalize(double[] a) {
double sum = 0;
for (int i = 0; i < a.length; i++) {
sum += a[i];
}
for (int i = 0; i < a.length; i++) {
a[i] = a[i]/sum;
}
return a;
}
Input: 1 2 3 4
Output: 0.1 0.2 0.3 0.4
publicstaticdouble[]normalize(double[]a){
双和=0;
for(int i=0;i
在第一种情况下,当方法返回时,原始数组将保持不变
在第二种情况下,原始数组将被修改(即使当它返回到调用它的位置时也是如此),而不管您随后将返回值设置为什么数组
这两种选择都是可行的,但这取决于具体情况和预期会发生什么。但是,我通常希望在将参数传递给方法时,在方法返回时不会修改参数
文档可以清楚地表明原始阵列将被修改,或者如果不被修改
旁注:
[1.0, 2.0, 3.0, 4.0]
[0.1, 0.2, 0.3, 0.4]
[1.0, 2.0, 3.0, 4.0]
[0.1, 0.2, 0.3, 0.4]
[0.1, 0.2, 0.3, 0.4]
如果您直接修改a
,而不是修改以下内容中包含的值,则此操作的工作方式不同:
public static void normalize(double[] a) {
a = new double[5];
}
在这种情况下,当方法返回时,a
将保持不变。不同之处在于,一个方法更新输入数组,而另一个方法保持数组完整并返回副本
两者都没有错(*),两种方式都有各自的位置,你只需要确保打电话的人知道发生了什么
如果就地更新,可以通过使方法void
而不是返回对同一数组的(冗余)引用来更清楚地说明这一点
(*)在现代实践中,更喜欢不可变的数据结构。因此,除非性能是一个真正的问题,否则使用“更安全”变量。在我看来,您正在创建一个具有新值的新变量。该方法接收一个var并返回另一个var
它对读者更友好。解释字节码行为,创建新数组或重用相同输入的区别我认为不是你想要的。因为很容易看出区别 我认为你在寻找的是对差异的概念分析。在我看来,任何语言中的“函数”都应该被视为数学函数。给定X和Y,函数返回Z。假设您有一个矩形,其
height=a
和width=b
。如果你想要它的面积,你通过a
和b
得到a
。如果你想要周长,你通过a
和b
得到P
这使您的代码更可读、可重用、更内聚、更可测试。它们都没有错。这只是一个问题,您是希望保持原始数组不变,还是希望在规范化时对其进行更改。检查以下代码的输出:
import java.util.Arrays;
public class Numbers {
public static void main(String[] args) {
double[] a = { 1, 2, 3, 4 };
System.out.println(Arrays.toString(a));
System.out.println(Arrays.toString(normalize1(a)));// No change in the array
System.out.println(Arrays.toString(a));
System.out.println(Arrays.toString(normalize2(a)));// The array will be changed
System.out.println(Arrays.toString(a));
}
public static double[] normalize1(double[] a) {
double[] b = new double[a.length];
double sum = 0;
for (int i = 0; i < b.length; i++) {
sum += a[i];
}
for (int i = 0; i < b.length; i++) {
b[i] = a[i] / sum;
}
return b;
}
public static double[] normalize2(double[] a) {
double sum = 0;
for (int i = 0; i < a.length; i++) {
sum += a[i];
}
for (int i = 0; i < a.length; i++) {
a[i] = a[i] / sum;
}
return a;
}
}
我建议您检查以了解更多信息。也许您不希望修改传入的数组。也许你需要它来做些别的事情。有时传入的数组应该被更改。但是,应以100点粗体字记录!这不是“错误”,这取决于您所处的情况-您希望保留原始值以供进一步计算(然后使用版本A)还是希望用规范化值覆盖它们(然后使用版本B)?一般来说,版本A可能“更好”/“更通用”,因为您可以在这两种情况下使用它,而B仅在不需要原始值的情况下才有用。顺便说一句,第二种情况可能会被误解:它返回一个数组,因此,我假设它是一个新数组-如果要更改原始数组,IMO
void
将更合适-但这并不意味着它是“错误的”-为什么称它为错误的?公平地说,在呈现给新值的代码中设置“a”也不会修改原始数组-只有在修改传递对象的属性/内部字段而不是更改引用时,它才会成为一个数组issue@josh.trow我把旁注改成了你提到的,谢谢你的意见。