Java坚持改变两个变量

Java insists on changing both variables

当 运行 我的 MVC 模型应用程序时,创建了 ApplicationModel 的 Singleton 实例。

当 运行 我的控制器 class 中的主要方法时,使用 setShops()List<Shop> 分配给 shops。如果shopsDefault = nullsetShops()也会继续分配同样的List<Shop>shopsDefault

到目前为止,还不错。

但是,当我调用 sortShopsByName() - 正如您在下面看到的使用 setShops() - shopsshopsDefault 都被排序了!为什么它不按预期对 shops 进行排序?

我的ApplicationModelClass...

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

因为是同一个列表。如果您想要不同的列表,请在将其分配给 shopsDefault 时制作一份副本(即 new ArrayList<Shop>(shops))。

shops 分配给 shposDefault 后,它们都引用同一个实例。因此,通过任一实例对实例所做的更改将通过两个引用可见。

如果这不是预期的行为,您可以在设置 null 时复制 shops 列表。例如:

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

在此代码中,您将两个成员设置为相同的列表引用:

this.shops = shops;
if (this.shopsDefault == null) {
   this.shopsDefault = shops;
}

如果要将它们分开,请使用以下命令:

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