0

I am a bit new to the Singleton Design Pattern and cannot understand the following example:

I have a singleton containing a single instance of an ArrayList of type Contact called contactList, where Contact is an object that has a String name and phone number.

Singleton:

public class AllContacts {

    private static AllContacts allContacts;
    private ArrayList<Contact> contactList;

    private AllContacts(){

        contactList = new ArrayList<Contact>();

        Contact paul = new Contact();
        paul.setName("John Smith");
        paul.setPhone("1234567890");
        contactList.add(paul);
    }

    public static AllContacts getInstance(){

        if(allContacts == null){
            allContacts = new AllContacts();
        }

        return allContacts;
    }

    public ArrayList<Contact> getContactList(){  
        return contactList;
    }
}

Contact:

public class Contact {

private String name;
private String phone;

    public Contact(){}

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }
}

I now get a Contact from the ArrayList in a different class and assign it to a variable called person. If I change the name of person using its setter method this also changes the Contact that is inside the ArrayList:

public class AnotherClass{
    ...

    public void changeName(){

        Contact person = AllContacts.getInstance().getContactList().get(0);
        person.setName("Steve Smith");

        //Prints Steve Smith
        System.out.println(AllContacts.getInstance().getContactList().get(0).getName()); 
     }

    ...
}

I don't quite understand how this works, seeing as I din't change the contactList ArrayList directly, but only another variable that was set equal to one of the items in the ArrayList.

barefootcoder
  • 87
  • 1
  • 3
  • 9
  • Because there is only one instance. – Elliott Frisch Jul 09 '14 at 00:50
  • Because singletons are not magic. They are merely objects that are wrapped with some special logic for obtaining their reference/pointer. Whatever you can do to the object by virtue of its class you can do to the singleton variety. – Hot Licks Jul 09 '14 at 00:59
  • @HotLicks when we have a singleton arrayList, Does it mean when we add an elements into it we will have another copy of the arrayList? am I right? or singleton can be immutable too? – Kick Buttowski Jul 09 '14 at 01:03
  • Singleton just means you can only have one instance of the class. That is all that it means. If this was not a singleton and you had one instance of your class it would be exactly the same. You don't have a "singleton arraylist", you just have a singleton class that happens to have an ArrayList member. – mclaassen Jul 09 '14 at 01:04
  • @KickButtowski -- Singleton *only* means that, if you use the singleton access mechanism, only one instance of that class will be allocated and a reference to the same instance of that class will be returned to all callers of the access mechanism. If the object is, say, an ArrayList, then the object itself is mutable and can be changed by anyone with access to the singleton. – Hot Licks Jul 09 '14 at 01:07
  • @HotLicks I thought singleton is immutable? – Kick Buttowski Jul 09 '14 at 01:09
  • @KickButtowski - You thought wrong. – Hot Licks Jul 09 '14 at 01:09
  • @HotLicks so what is this? http://stackoverflow.com/questions/4887517/how-to-make-an-immutable-singleton-in-java – Kick Buttowski Jul 09 '14 at 01:10
  • 1
    @KickButtowski - It's discussing an immutable singleton. If the object "dispensed" by a singleton access method is immutable then that object is immutable. Nothing more. A String is immutable, an ArrayList is not. – Hot Licks Jul 09 '14 at 01:12

1 Answers1

2

This is because instances of classes are passed by reference in Java. When you assign an item in the list to a variable you are really just assigning a reference to the single instance that actually exists somewhere and also has a reference to it in the list. When you change a property of the object through any reference to it you are changing the one and only instance that exists. The fact that you are using a singleton class has nothing to do with this.

mclaassen
  • 5,018
  • 4
  • 30
  • 52
  • Actually everyting in java is "passed by value", but you expressed the "what happening there" so well, that I will +1 you :D – libik Jul 09 '14 at 00:55
  • 1
    Ah yes, to clarify for the OP, what is actually stored in the list is a reference to the instance and when you assign it to a variable you are copying the reference by value, but it is still just another reference to the single instance. – mclaassen Jul 09 '14 at 00:57
  • @libik as far as I know passed by value works for primitive types – Kick Buttowski Jul 09 '14 at 01:00
  • That makes a lot of sense, thank you. I didn't know it was passed by reference. – barefootcoder Jul 09 '14 at 01:02
  • @KickButtowski - mclaassen has amazing ability to describe :), read his comment he did after my comment. There is difference between "copy the reference" and "pass by reference". – libik Jul 09 '14 at 01:02
  • @libik I did not object that at all. I just shared what I know :) – Kick Buttowski Jul 09 '14 at 01:05
  • @libik my guess is when an element is added to a singlton arrayList, an new arrayList is made? – Kick Buttowski Jul 09 '14 at 01:07
  • Why would a new ArrayList be created just by adding a new item to it? It wouldn't matter whether it's singleton or not, it's just an instance of a class. – mclaassen Jul 09 '14 at 01:09