我遇到了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);
}
}
修改
这是作业,但是当我想添加标签时,显示该标签已不再使用。
答案 0 :(得分:4)
我想这个:
public class Employees extends LinkedList<Employee> {
private LinkedList<Employee> employees;
将创造一个混乱的世界。你们都在扩展一个列表,在那个类中你要维护一个单独的列表。当您致电addWerknemer()
时,您将添加到内部列表中。致电get()
时会发生什么?既然你没有覆盖它,你就在基类上调用get()
,这是一个不同的列表!
在不检查其余代码的情况下,我怀疑这是问题的根本原因。
您有两种选择:
Employees
扩展List
Employees
包含List
我更喜欢第二种。您可以更改基础集合(例如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
)。您必须实施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。员工仅延伸LinkedList
且不包含一个
丢弃方法addWerknemer(Employee emp)
和复制构造函数Employees(Employees)
以及内部列表。这样您就不会覆盖LinkedList
的现有实现。这种方法或多或少没用,因为您基本上只需将LinkedList
重命名为Employees
并添加/更改任何内容。因此我不推荐这种方法。