6

I have an employee object

I Cannot update the employee Object

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;

I am initially setting a employee list but want to create copy of that and then make changes to it. Even though I am creating new list its still changing the original list

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());

    }
}

The output is coming as 11.

Is there any easier way to clone from original list and any changes should not be applied to original list object and just the new list I created

Makky
  • 17,117
  • 17
  • 63
  • 86
  • 1
    how about making it immutable and provide a copy-constructor? – Eugene Dec 15 '17 at 13:12
  • I have editied the question. Is there no way in Java to do that? – Makky Dec 15 '17 at 13:17
  • 1
    A user of your experience could have heard of "do prior research" before ... – GhostCat Dec 15 '17 at 13:35
  • You need to be aware that in Java ***Everything is an object*** and everything is a reference except for primitive types to save memory. The first elements of both your arrays **are the same object**. – Daniel Cheung Dec 15 '17 at 13:39
  • @GhostCat You realize there has been great answers to this question? I wasn't expecting comment from user of your experience. – Makky Dec 15 '17 at 13:41
  • https://meta.stackoverflow.com/questions/261592/how-much-research-effort-is-expected-of-stack-overflow-users – GhostCat Dec 15 '17 at 14:14
  • @GhostCat Thanks. Suggest you start helping than doing admin job which you're NOT – Makky Dec 15 '17 at 14:16
  • The *admins* are the people working for stackexchange.com. It is not their job to remind users about the policies of this site. It is also not the job of the *moderators*. The whole idea of this community is that each user is free to talk to any other user ... and for example remind on the policies should be uphold. I understand that you don't like to be reminded about that ... but you just received helpful feedback. And make no mistake: if you were a newbie with +1 reputation, you would have probably seen a lot of downvotes and most likely, your question would have been deleted already. – GhostCat Dec 15 '17 at 14:48
  • @GhostCat OK Sure thanks. I'll keep that in mind – Makky Dec 15 '17 at 14:54

3 Answers3

12

First make a copy constructor in your Employee class:

    public Employee(Employee employee) {
        this.id = employee.id;
        this.age = employee.age;
        this.gender = employee.gender;
        this.firstName = employee.firstName;
        this.lastName = employee.lastName;
    }

And then you can make a deep copy with Java 8 streams:

List<Employee> listTwo = employeeList.stream().map(item -> new Employee(item)).collect(Collectors.toList());
Planck Constant
  • 1,406
  • 1
  • 17
  • 19
11

It is not changing the original list, but it is changing the object which is contained in both lists.

In cases like this, it might be very useful to make the employee objects unmodifiable and provide a possibility to create a copy object with changed properties with respect to the original one.

If you absolutely cannot modify the Employee object (not even add a copy constructor), you instead can implement an own copy/clone method (not connected to the Cloneable interface, which is said to be broken):

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

and then do

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

or just

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

(essentially the same what Uata suggests, but do the copying on your own).

glglgl
  • 89,107
  • 13
  • 149
  • 217
3

As you can not change the Employee class itself you can make a helper method which deep copies a Employee instance (you could of course also invoke the constructor directly, but I find a simple method cleaner):

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

and with that you then can Stream the list and copy each element with a map operation:

List<Employee> employeesCopy = employees.stream() // Stream<Employee>
    .map(e -> copy(e))                            // Stream<Employee>
    .collect(Collectors.toList());                // List<Employee>
Lino
  • 19,604
  • 6
  • 47
  • 65