【问题标题】:Java 8 List copy [duplicate]Java 8列表副本[重复]
【发布时间】:2018-05-29 16:59:52
【问题描述】:

我有一个员工对象

我无法更新员工对象

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;

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

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。

有没有更简单的方法可以从原始列表中克隆,并且任何更改都不应该应用于原始列表对象,而只是我创建的新列表

【问题讨论】:

  • 如何让它不可变并提供一个复制构造函数?
  • 我已经编辑了这个问题。 Java有没有办法做到这一点?
  • 有您的经验的用户可能听说过“做事先研究”...
  • 您需要注意,在 Java 中 一切都是对象,除了基本类型之外,一切都是引用以节省内存。两个数组的第一个元素是同一个对象
  • @GhostCat 你知道这个问题有很好的答案吗?我没想到用户会对您的体验发表评论。

标签: java arraylist java-8


【解决方案1】:

由于您无法更改 Employee 类本身,因此您可以创建一个帮助方法来深度复制 Employee 实例(您当然也可以直接调用构造函数,但我找到了一个简单的方法清洁器):

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

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

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

【讨论】:

    【解决方案2】:

    它并没有改变原始列表,而是改变了两个列表中包含的对象。

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

    我不确定clone() 是否会创建对象的深层副本。如果是,all is fine,如果不是,你可以use streams to create a deep copy

    如果你绝对不能修改Employee 对象(甚至不添加复制构造函数),你可以这样做:

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

    然后做

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

    或者只是

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

    (与 Uata 建议的基本相同,但您自己进行复制)。

    【讨论】:

    【解决方案3】:

    首先在您的 Employee 类中创建一个复制构造函数:

        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 流进行深度复制:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-23
      • 2016-02-23
      • 2017-07-03
      • 1970-01-01
      • 2020-09-06
      • 2017-01-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多