链接列表复制构造函数

时间:2012-11-30 10:30:08

标签: java linked-list copy-constructor

我遇到了Java中Linkend List的复制构造函数的问题。 我试图复制的列表大小为3,当我使用复制构造函数时,列表为空。

当我使用克隆方法尝试此操作时,一切都很好。 我已经看了很长一段时间了,我感觉它是如此明显。我只是 不要看,这是代码。

public class Employee {

    private String name;
    private double salary;

    public Employee(String name, double salary){

        this.name = name;
        this.salary = salary;
    }

    public void setname(String name){
        this.name = name;
    }

    public void setsalary(double salary){
        this.salary = salary;
    }

    public String getname(){
        return this.name;
    }

    public double getsalary(){
        return this.salary;
    }
}


    public class Main {

    public static void main(String[] args) {

        Employees employees = new Employees();
        employees.add(new Employee("Employee1", 2500.00));
        employees.add(new Employee("Employee2", 2400.00));
        employees.add(new Employee("Employee3", 2000.00));

        Employees employeesCopy2 = new Employees(employees);
        Employees employeesCopy = (Employees) employees.clone();

        System.out.println(employees.size());
        System.out.println(employeesCopy2.size());
        System.out.println(employeesCopy.size());
    }

}

    import java.util.LinkedList;

public class Employees extends LinkedList<Employee> {

    private static final long serialVersionUID = 1L;
    private LinkedList<Employee> employees;

    public Employees(){ 

        employees = new LinkedList<Employee>();
    }

    public Employees(Employees w){

        employees = new LinkedList<Employee>(w);
    }

    public void addWerknemer(Employee w){
        employees.add(w);
    }
}

修改

这是作业,但是当我想添加标签时,显示该标签已不再使用。

3 个答案:

答案 0 :(得分:4)

我想这个:

public class Employees extends LinkedList<Employee> {

    private LinkedList<Employee> employees;

将创造一个混乱的世界。你们都在扩展一个列表,在那个类中你要维护一个单独的列表。当您致电addWerknemer()时,您将添加到内部列表中。致电get()时会发生什么?既然你没有覆盖它,你就在基类上调用get(),这是一个不同的列表!

在不检查其余代码的情况下,我怀疑这是问题的根本原因。

您有两种选择:

  1. Employees扩展List
  2. Employees包含List
  3. 我更喜欢第二种。您可以更改基础集合(例如Set,可能是Map以获得更好的查找性能),而不是更改公开的界面。

答案 1 :(得分:1)

您正在扩展LinkedList,但在该扩展程序中也有LinkedList。最初使用add方法添加Employee个实例,因此它们会被添加到Employees列表本身,但是当您使用复制构造函数时,将这些员工复制到{{1你employees班里面的字段。

当您调用Employees方法时,它将使用size()对象本身的LinkedList,因此在第一个列表中它是3,但在第二个列表中它是0现在,员工都在包含列表中,而不在对象本身中。

在这种情况下,你可能延伸Employees。或者如果你这样做,那么不要使用像LinkedList这样的单独字段,它也包含LinkedList。

答案 2 :(得分:0)

您的困惑来自这样一个事实:Employees 是列表,包含列表。当你使用

employees.add(new Employee("Employee1", 2500.00));

您将员工添加到外部列表中。当你使用

employees.addWerknemer(new Employee("Employee1", 2500.00));

您将员工添加到内部列表中。由于您已覆盖构造函数Employees(Employees es),因此不会克隆外部列表,而只覆盖内部列表。由于您没有覆盖clone()克隆外部列表,但内部。这是相当混乱的,也很可能不是你想要的。因此,我提出以下改动之一:

<强> 1。 [Preferred]员工只包含一个列表,而不是扩展一个
跳过extends LinkedList<Employee>并仅使用内部列表。您必须使用方法addWerknemer(Employee emp)添加到列表中(或将其名称更改为add)。您必须实施sizeclone以及您希望使用的其他方法。如果你想对此非常干净,你甚至可以上课implement Listimplement Collection左右。这样,您仍然可以将您的班级视为java.util.Collection。我不认为这在你的情况下是必要的。您还需要实现所有接口方法(有很多)。示例实现看起来像这样。您仍然必须实施size

public class Employees /*implements List<Employees>*/ {
    private static final long serialVersionUID = 1L;
    private LinkedList<Employee> employees;

    public Employees(){ 
        employees = new LinkedList<Employee>();
    }

    public Employees(Employees w){
        employees = new LinkedList<Employee>(w);
    }

    public void add(Employee w){
        employees.add(w);
    }

    public Employees clone() {
        return employees.clone();
    }

    // add more methods as you need them (like remove, get, size, etc)
}

<强> 2。员工仅延伸LinkedList且不包含一个 丢弃方法addWerknemer(Employee emp)和复制构造函数Employees(Employees)以及内部列表。这样您就不会覆盖LinkedList的现有实现。这种方法或多或少没用,因为您基本上只需将LinkedList重命名为Employees并添加/更改任何内容。因此我不推荐这种方法。