为什么我的Java深度复制代码告诉我;作业要求深度而非浅层副本“;?

为什么我的Java深度复制代码告诉我;作业要求深度而非浅层副本“;?,java,Java,我正在尝试提交此声音处理程序,但我不断收到以下错误: 作业需要深度而非浅层副本。您只是复制指针,还是复制数组的内容 我想我在我的公共void集上做了一个肤浅的复制(double[]mySamples),但我对Java是新手,真的不知道该怎么做 public class Sound { private double[] temp; private double[] samples; public Sound() { samples = null;

我正在尝试提交此声音处理程序,但我不断收到以下错误:

作业需要深度而非浅层副本。您只是复制指针,还是复制数组的内容

我想我在我的公共void集上做了一个肤浅的复制(
double[]mySamples
),但我对Java是新手,真的不知道该怎么做

public class Sound
{
    private double[] temp;
    private double[] samples;

    public Sound() {
        samples = null;
    }

    public Sound(Sound s) {
        int j = 0;
        double[] source = s.samples;
        double temp[] = new double[source.length];
        for(int i = 0; i < source.length; i++) {
            temp[j] = source[i];
        }
        samples = temp;
    }

    public double[] get() {
        return samples;
    }

    public void set(double[] mySamples) {
        if (mySamples == null) {
            throw new IllegalArgumentException("samples cannot be null");
        } else {
            samples = mySamples;
        }
    }


    public void increaseVol(double percent) {
        double [] result = new double[samples.length];
        for (int i = 0; i < samples.length; i++) {
            double reduce = samples[i] * percent;
            result[i] = samples[i] + reduce;
        }
        samples = result;
    }

    public void wavSave(java.lang.String fileName) {
        WavIO.write(fileName, samples);
    }
}
公共类声音
{
私人双[]临时工;
私人双[]样本;
公共声音{
样本=空;
}
公共声音(s声){
int j=0;
双[]源=s样本;
double temp[]=新的double[source.length];
for(int i=0;i
我认为您需要做两个更改-
1你的构造函数对这些样本做了一些奇怪的事情(可能是它自己导致了你的错误)-我不确定你想做什么,但我认为你应该推迟设置

public Sound(Sound s) {
  int j = 0;
  set(s.samples);
}
2只需将样本数组复制到集合中并存储即可

public void set(double[] mySamples) {
  if (mySamples == null) {
    throw new IllegalArgumentException(
        "samples cannot be null");
  } else {
    samples = new double[mySamples.length];
    for (int i = 0; i < mySamples.length; i++) {
      samples[i] = mySamples[i];
    }
  }
}
公共无效集(双[]mySamples){
if(mySamples==null){
抛出新的IllegalArgumentException(
“样本不能为空”);
}否则{
样本=新的双精度[mySamples.length];
for(int i=0;i
是的,你在做“浅”拷贝。Java中的数组类似于指针,因为如果返回或设置数组,它只是指向该数组的指针(实际上是引用)。使用当前代码,不同的声音对象很容易引用相同的底层数组,这可能不是您想要的

set
方法中,您需要复制数组的内容,而不仅仅是复制对该数组的引用

Sound(Sound s)
构造函数中正确复制数组的内容。但是,不需要手动分配新数组并编写for循环来复制值。只需调用
java.util.Arrays.copyOf()
来复制它。您可以在
set
方法中使用类似的技术


get
方法还存在从声音对象内部返回数组引用的问题。调用者现在有了对声音对象内部状态的引用,并且可以对其进行操作。这可能是您想要的,也可能不是您想要的。

基本体数组和自动装箱引用类型数组(来自基本体)是最终的且不可变的。因此,它们是
clone()
方法的理想候选

您可以编辑此代码:

public void set(double[] mySamples) {
    if (mySamples == null) {
        throw new IllegalArgumentException(
            "samples cannot be null");
    } else {
        samples = new double[mySamples.length];
        for (int i = 0; i < mySamples.length; i++) {
            samples[i] = mySamples[i];
        }
    }
}
公共无效集(双[]mySamples){
if(mySamples==null){
抛出新的IllegalArgumentException(
“样本不能为空”);
}否则{
样本=新的双精度[mySamples.length];
for(int i=0;i
使用相同的功能和卓越的性能:

public void set(double[] mySamples) {
    if (mySamples == null || mySamples.length < 1) {
        throw new IllegalArgumentException(
            "samples cannot be null or empty");
    }
    samples = mySamples.clone();
}
公共无效集(双[]mySamples){
if(mySamples==null | | mySamples.length<1){
抛出新的IllegalArgumentException(
“样本不能为null或空”);
}
samples=mySamples.clone();
}
这是安全的,因为
double
s是不可变的和基本的,因此在这种情况下浅拷贝与深拷贝相同。它也是安全的,因为不能对
double
进行子类化,因此
clone()
不可能造成危害

此外,数组上的
clone()
的性能比在代码中迭代数组并逐元素复制要快得多


TL;DR:复制基元数组(或对应于基元的自动装箱引用类型数组)很可能是唯一一种使用
clone()
方法的理想情况。

请编辑代码,使其显示合理的缩进。请指出哪一行显示错误。这是我第一次在这个网站上,真的不知道你所说的合理缩进是什么意思。不管怎样,谢谢你的帮助。你可以在代码行中添加空格,这些空格应该缩进,就像代码块中的代码一样。这与本网站无关,只涉及基本的Java代码格式化。这一点很重要,因为阅读代码越容易,就越容易帮助您。现在再说一遍,哪一行显示您的错误?