1

I am trying to understand how the below code is working:

public class Sample {

    public static void main(String[] args) {
        Name defaultName = new Name();
        defaultName.setFirstName("defaultfirst");
        defaultName.setLastName("defaultlast");

        Name name1 = new Name();
        name1.setFirstName("name1First");
        name1.setLastName("name1Last");

        Name name2 = new Name();
        name2.setFirstName("name2First");
        name2.setLastName("name2Last");

        List<Name> namesNew = new ArrayList<Name>();
        namesNew.add(name1);
        namesNew.add(name2);

        List<Name> names = new ArrayList<Name>();
        for(int i=0;i<2;i++){
            Name name = defaultName;
            name.setFirstName(namesNew.get(i).getFirstName());
            name.setLastName(namesNew.get(i).getLastName());
            System.out.println(i+ " name " +name);
            names.add(name);
            System.out.println(i +" " +names);
        }

        System.out.println(names);

    }

}

when the first loop is executed the value of names[0] is being set to name1 but after the send loop is getting executed names[1] and also name[0] is changing to name2 even though i am not setting names[0] anywhere in that code.

Can someone tell me how this is behaving and also what i should do for names[0] to not change.

java2890
  • 201
  • 1
  • 4
  • 10

2 Answers2

2

Don't do:

Name name = defaultName;

With this you're continually changing the state of a single object within your for loop, and this is not what you want. Instead create a new Name object within your loop:

Name name = new Name();
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • This is a sample of what i am trying to implement. I have to set few name objects to a default value and only change few values in them to a different value. To be more clear suppose i need to create n name objects which should have certain attributes like lastName to same as from deafultName but few attributes to change to a different value. how can i achive that?? – java2890 Apr 20 '16 at 01:26
  • @java2890: consider 1) giving Name default values in the default constructor. or 2) create a static method that creates a **new** default Name object. Either or, just don't do what you're currently doing as it's guaranteed to fail for just the reason I've presented above. – Hovercraft Full Of Eels Apr 20 '16 at 01:29
  • for example : I have to create List with 3 objects in it . They have to be copied from defaultName and for 1st objects firstName has to change to X and 2nd objects lastName has to change to Y and 3rd objects firstName has to change to Z . These attributes that change can be different. how can i achieve that? – java2890 Apr 20 '16 at 01:30
  • @java2890: as I just stated above. – Hovercraft Full Of Eels Apr 20 '16 at 01:46
0

The problem here is that you're setting name to a reference to defaultName rather than copying defaultName to name. So in each iteration of your loop you're talking about the same object.

I don't know if you have control of Name or not. But if you do here's a way you can deal with it. This is called a copy constructor.

public class Name { 
    String firstName;
    String lastName;
    public Name(Name oldName) {
       this.firstName = oldName.getFirstName();
       this.lastName = oldName.getLastName(); 
    }
    public Name() {
    }
}

Then in your loop you could do

Name name = new Name(defaultName); 

Although it does seem to me that the default name values are not actually intended to be used in your loop. So you could very well omit any references to the default name in the first place. And do something like this.

   for (int i = 0; i < 2; i++) {
      Name name = new Name(); 
      name.setFirstName(namesNew.get(i).getFirstName());
      name.setLastName(namesNew.get(i).getLastName());
      names.add(name);
   }

Although personally, I don't know the reason for having defaultName be an instance of name vs just setting the name parameters to the default values in the Name class (If you control the Name class).

That would be done like this

public class Name { 
  String firstName = "Firstname"; 
  String lastName = "Lastname"; 
}
hsanders
  • 1,913
  • 12
  • 22