0

我在使用 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);
    }
}

编辑

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

4

3 回答 3

4

我认为这:

public class Employees extends LinkedList<Employee> {

    private LinkedList<Employee> employees;

将创造一个混乱的世界。你们都在扩展一个列表,并且在该类中维护一个单独的列表。当你打电话时,addWerknemer()你会添加到内部列表中。当你打电话时会发生什么get()?由于您没有覆盖它,因此您正在调用get()基类,这是一个不同的列表!

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

你有两个选择:

  1. Employees延伸List
  2. Employees包含一个List

我更喜欢第二个。您可以更改底层集合(例如 a Set,也许是 aMap以获得更好的查找性能)而不更改公开的接口。

于 2012-11-30T10:35:16.133 回答
1

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

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

在这种情况下,您可能不应该扩展LinkedList. 或者,如果您这样做,则不要使用employees也包含 LinkedList 的单独字段。

于 2012-11-30T10:36:31.230 回答
0

您的困惑来自这样一个事实,即Employees两者都是列表并且包含列表。当你使用

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

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

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

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

1. [首选]员工只包含一个列表,不扩展一个
跳过extends LinkedList<Employee>并且只使用内部列表。您将不得不使用您的方法addWerknemer(Employee emp)添加到您的列表中(或将其名称更改为add)。您将必须实现size以及clone您希望使用的其他方法。如果您想对此非常干净,甚至可以上课implement List左右implement 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.Employees 只扩展LinkedList并且不包含一个
扔掉你的方法addWerknemer(Employee emp)和复制构造函数Employees(Employees)以及你的内部列表。这样您就不会覆盖现有的LinkedList. 这种方法或多或少没用,因为您基本上只是重命名LinkedListEmployees添加/更改任何内容。因此我不推荐这种方法。

于 2012-11-30T11:05:57.780 回答