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我把旁注改成了你提到的,谢谢你的意见。