清空全局ArrayList也会清空另一个吗?

3

我遇到了一个非常奇怪的错误。

我正在编写一个通用类,并在其中一个方法中发现了一件奇怪的事情。这里是部分类的代码:

public abstract class GenericFragment<M extends BaseModel, A extends BaseAdapter> extends HtmlFragment {

    private ArrayList<M> datas = new ArrayList<>();    
    private A adapter;

    protected abstract String getUrl();

    protected abstract A setAdapter();

    protected A getAdapter() {

        if(adapter == null) {
             adapter = setAdapter();
        }

        return adapter;
    }

    protected ArrayList<M> getDatas() {
        return datas;
    }

    protected void refreshData(ArrayList<M> datas) {

        Log.d("before glob", String.valueOf(this.datas.size()));
        Log.d("before loc", String.valueOf(datas.size()));

        this.datas.clear();

        Log.d("clear glob", String.valueOf(this.datas.size()));
        Log.d("clear loc", String.valueOf(datas.size()));

        this.datas.addAll(datas);

        Log.d("after glob", String.valueOf(this.datas.size()));
        Log.d("after loc", String.valueOf(datas.size()));

        getAdapter().notifyDataSetChanged();
    }
}

当我调用函数 refreshData() 时,全局 ArrayList 被清除,但是本地的 ArrayList 也被清除。以下是日志:

D/niviel: before glob: 5
D/niviel: before loc: 5
D/niviel: clear glob: 0
D/niviel: clear loc: 0
D/niviel: after glob: 0
D/niviel: after loc: 0

我只想将本地数组复制到全局数组。

编辑:

该函数是在子类中调用的。

requestData(activity, new requestDataCallback() {
    @Override
    public ArrayList<? extends BaseModel> parseDatas(Document document) {
        return RecordProvider.getRecord(activity, document);
    }

    @Override
    public void runOnUIThread(ArrayList<? extends BaseModel> datas) {

        refreshData((ArrayList<Record>) datas);
    }

});

你传递给 refreshData 的参数是什么?如果是 this.datas,为什么不期望它会同时清除 "both" this.datasdatas?("both" 是因为它们是同一个实例)。 - Andy Turner
在 setter 中设置了类字段并在 refreshData 中使用了吗? - KJaeg
你如何传递ArrayList或者如何从全局ArrayList中复制? - intellignt_idiot
ArrayList来自回调函数,该函数在回调的子类中被调用。 - Herel Adrastel
3个回答

3
在您的refreshData()函数中,您使用的两个列表是相同的。
protected void refreshData(ArrayList<M> datas) {

Log.d("before glob", String.valueOf(this.datas.size()));
Log.d("before loc", String.valueOf(datas.size()));

//here you are clearing datas
this.datas.clear();

//so now your datas size will be 0

Log.d("clear glob", String.valueOf(this.datas.size()));
Log.d("clear loc", String.valueOf(datas.size()));

//here you are adding it to datas again whose size is already 0
this.datas.addAll(datas);

Log.d("after glob", String.valueOf(this.datas.size()));
Log.d("after loc", String.valueOf(datas.size()));

getAdapter().notifyDataSetChanged();
}

我不明白它们怎么可能是相同的:即使我更改本地数组的名称,问题仍然存在。 - Herel Adrastel

1

好的,我最终调试了我的代码。我注意到函数refreshData()正在传递全局ArrayList参数。


0

了解Java内存模型。List是数据的引用类型,因此您可以使用相同的列表。


哇,谢谢你的快速回答。那么根据你的看法,解决这个问题的最佳方法是什么? - Herel Adrastel
例如,您可以使用这个链接。如果您能提供使用refreshData函数的代码部分,那就太好了。 - Stanislav Parkhomenko
问题是,如果我创建一个新的数组,适配器就不会工作了,对吗? - Herel Adrastel
你有一个ArrayList添加到了适配器中,如果你改变不同的ArrayList或它的拷贝,那么你的适配器中当然不会出现任何更改。 - Stanislav Parkhomenko
是的,这就是为什么我使用clear和addAll的原因。我想要的只是用本地数组替换全局数组,以便调用notifydatasetchanged。 - Herel Adrastel
您可以随时调用notifyDataSetChanged。 - Stanislav Parkhomenko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接