关于arraylist:Java 8 List复制

Java 8 List copy

本问题已经有最佳答案,请猛点这里访问。

我有一个员工对象

我无法更新员工对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Employee {

    public Employee(Integer id, Integer age, String gender, String fName, String lName) {
        this.id = id;
        this.age = age;
        this.gender = gender;
        this.firstName = fName;
        this.lastName = lName;
    }

    private Integer id;
    private Integer age;
    private String gender;
    private String firstName;
    private String lastName;

我最初是在设置员工列表,但想创建该列表,然后对其进行更改。 即使我正在创建新列表,它仍然会更改原始列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class ListTest {

    public static void main(String[] args) {

        List<Employee> employeeList = new ArrayList<>();
        Employee employee = new Employee(1, 1,"MALE","TEST","TEST");
        employeeList.add(employee);

        List<Employee> listTwo = new ArrayList<>();
        listTwo.addAll(employeeList);

        listTwo.get(0).setAge(11);

        System.out.println(employeeList.get(0).getAge());

    }
}

输出为11。

有什么简单的方法可以从原始列表进行克隆,并且不应将任何更改应用于原始列表对象,而仅应用于我创建的新列表


首先在Employee类中创建一个副本构造函数:

1
2
3
4
5
6
7
    public Employee(Employee employee) {
        this.id = employee.id;
        this.age = employee.age;
        this.gender = employee.gender;
        this.firstName = employee.firstName;
        this.lastName = employee.lastName;
    }

然后,您可以使用Java 8流进行深拷贝:

1
List<Employee> listTwo = employeeList.stream().map(item -> new Employee(item)).collect(Collectors.toList());

它不是在更改原始列表,而是在更改两个列表中包含的对象。

在这种情况下,使员工对象不可修改并提供创建副本对象(相对于原始对象更改属性)的可能性可能非常有用。

我不确定clone()是否创建对象的深层副本。如果是这样,那么一切都很好,否则,您可以使用流来创建深层副本。

如果您绝对不能修改Employee对象(甚至不添加副本构造函数),则可以这样做:

1
2
3
public static Employee clone(Employee original) {
    return new Employee(original.getID(), original.getAge(), original.getGender(), original.getFirstName(), original.getLastName());
}

然后做

1
employeeList.stream().map(item -> clone(item)).collect(Collectors.toList());

要不就

1
employeeList.stream().map(<thisclassname>::clone).collect(Collectors.toList());

(基本上与Uata的建议相同,但可以自行复制)。


由于您不能更改Employee类本身,因此可以制作一个辅助方法,该方法可以深度复制Employee实例(您当然也可以直接调用构造函数,但是我发现了一个简单的方法清除器):

1
2
3
public static Employee copy(Employee original){
    return new Employe(original.id, original.age, original.gender, original.fname, original.lname);
}

然后,您就可以流式传输列表并使用map操作复制每个元素:

1
2
3
List<Employee> employeesCopy = employees.stream() // Stream<Employee>
    .map(e -> copy(e))                            // Stream<Employee>
    .collect(Collectors.toList());                // List<Employee>