【问题标题】:how to copy an array of objects to another array? [duplicate]如何将对象数组复制到另一个数组? [复制]
【发布时间】:2013-05-28 11:19:19
【问题描述】:

我正在用 Java 制作一个简单的对象数组,我的部分代码如下

public class Student{
     private String name;
     private double score;
     public Student(String name){
        this.name=name;
        this.score=score
}

public class Classroom{
    private Student[] listStu;
    private int sc;
    public addStu(Student stu){
           listStu[sc]=stu;
           sc++;
    }
    public Student[] getClassroom(){
            return listStu;
    }
    public int getNum(){
           return sc;
    }
    public printList(){
          for (int i=0;i<sc;i++){
              System.out.pritnln(listStu[i].getName());
          }
}

在主类中我编写了这个:

Classroom c=new Classroom();
Student[] stuList;
int nStu;
Student s1=new Student("michael",3.0);
Student s2=new Student("larry",4.0);
c.addStu(s1);
c.addStu(s2);
stuList=c.getClassroom();
nStu=c.getNum();

问题是当我在主类中修改我的类 stuList 的对象时,类似于:

stuList[0].setName("peter");

我看到当我调用我的 printList 方法时,我的数组中的数据也被修改了(在我的例子中,“michael”的名字被“peter”改变了)。我的问题是如何将我的对象数组复制到主类的 stuList 中,以便该数组不会干扰我的原始数据?这个程序真的有必要吗?或者这种情况不太可能发生?

谢谢

【问题讨论】:

  • 传递参数是 java 的关键。您的调用 c.addStu() 只是传递对您的学生对象的引用。因此,您的对象仍然是相同的,并且绝对不依赖于使用哪个特定引用来进行实际的对象操作,结果将永远相同,因为只有一个对象。创建对象的副本是解决问题的好方法。看看这篇文章:en.wikipedia.org/wiki/Clone_%28Java_method%29

标签: java oop


【解决方案1】:

通常您会使用List&lt;Student&gt; 而不是编写自己的集合,但是问题是一样的。你有一个数组的浅拷贝,看起来你想要一个深拷贝。您需要使用包含相同信息的新学生对象创建一个新数组,而不是引用该数组。

显然,这是乏味且缓慢的,一般建议是避免更改从集合中获得的任何集合(例如数组)。即使用 setName 是一个坏主意,除非“Michael”将他的名字改为“Peter”。如果你想用 Peter 替换 michael,你有一个 enw Student,它应该替换旧的 Student 参考。

【讨论】:

    【解决方案2】:

    Student 类进行这些更改:

    class Student implements Cloneable {
    
        protected Student clone() throws CloneNotSupportedException {
            return (Student) super.clone();
        }
    

    Classroom类中添加这个方法:

    public Student[] deepCopy() throws CloneNotSupportedException {
        Student[] deepCopy = new Student[this.listStu.length];
        for (Student student : this.listStu) {
            deepCopy[0] = student.clone();
        }
        return deepCopy;
    }
    

    然后在main 方法中:

    Student[] backupList = c.deepCopy();
    backupList[0].setName("test");
    System.out.println(backupList[0].getName());
    System.out.println(stuList[0].getName());
    

    将输出:

    test
    michael
    

    您的代码中似乎还有一些语法错误:

        public Student(String name){
        this.name=name;
        this.score=score
    }
    

    缺少右括号}(来自方法的那个),分数不是参数,缺少;

    但是,如果您采用此解决方案,请确保您记录更多关于 cloning in Java 的信息

    【讨论】:

      【解决方案3】:

      在 Java 中,您使用指针,这就是为什么当您在第二个数组中修改时,它也在第一个数组中进行。尝试改变这个:

      public addStu(Student stu){
             listStu[sc]=stu;
             sc++;
      }
      

      到这里:

      public addStu(Student stu){
             listStu[sc]=(Student) stu.clone();
             sc++;
      }
      

      看看它是否有效。

      【讨论】:

        【解决方案4】:

        要复制数组,请使用 System.arraycopy(请参阅 http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#arraycopy%28java.lang.Object,%20int,%20java.lang.Object,%20int,%20int%29)。

        但请记住:Java 中的对象数组是对数组元素的引用数组。与克隆集合类似,副本将包含相同的元素。对于您的用例,您必须复制元素本身。

        【讨论】:

          【解决方案5】:

          你可以这样做:

          Student newStudent = stuList[0];
          newStudent.setName("peter");
          

          现在你有了一个新对象,如果你改变它,数组值不会受到影响。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-04-13
            • 1970-01-01
            • 2015-04-13
            • 2017-09-13
            • 1970-01-01
            • 2013-04-20
            • 2019-05-12
            • 1970-01-01
            相关资源
            最近更新 更多