Search code examples
javasetteraccessor

Java insists on changing both variables


When running my MVC model application, a Singleton instance of ApplicationModel is created.

When running the main method in my controller class, a List<Shop> is assigned to shops using setShops(). If shopsDefault = null, setShops() will also continue to assign the same List<Shop> to shopsDefault.

So far, so good.

However, when I call sortShopsByName() - which as you can see below uses setShops() - both shops AND shopsDefault become sorted! Why does it not just sort shops as intended?

My ApplicationModel Class...

import java.util.*;

public class ApplicationModel {

    //static variables
    private static ApplicationModel instance = null;

    //instance variables
    private List<Shop> shops;
    private List<Shop> shopsDefault;

    //constructors
    private ApplicationModel() {}

    //getInstance method
    public static ApplicationModel getInstance() {
        if (instance == null) {
            instance = new ApplicationModel();
        }

        return instance;
    }

    //getters and setters
    public List<Shop> getShops() {
        return shops;
    }

    public void setShops(List<Shop> shops) {
        this.shops = shops;
        if (this.shopsDefault == null) {
            this.shopsDefault = shops;
        }
    }

    public List<Shop> getShopsDefault() {
        return this.shopsDefault;
    }


    //Shop methods
    public void sortShopsByName() {
        List<Shop> shops = this.getShops();
        Collections.sort(shops);
        this.setShops(shops);
    }

    public void returnShopsToDefaultOrder() {

        List<Shop> shopsDefault = this.getShopsDefault();
        setShops(shopsDefault);
    }
}

Solution

  • Once you assign shops to shposDefault, they both reference the same instance. Changes made to the instance via either instance will, thus, be visible via both references.

    If this is not the intended behavior, you could copy the shops list when setting null. E.g.:

    public void setShops(List<Shop> shops) {
        this.shops = shops;
        if (this.shopsDefault == null) {
            this.shopsDefault = new ArrayList<>(shops);
        }
    }