Java 为什么原始数组项也会在ArrayAdapter中被删除?

Java 为什么原始数组项也会在ArrayAdapter中被删除?,java,android,android-arrayadapter,deep-copy,Java,Android,Android Arrayadapter,Deep Copy,我通过适配器的add和clear从适配器对象中添加和删除值,它们正在将元素删除和添加到列表中,而该列表不会从适配器内的任何位置引用。我有一个orig列表,它位于适配器外部,有一个从适配器内部到未更改外部引用的引用,在适配器内部,我只引用了一个新列表,我使用旧的原始列表填充了相同的对象。为什么新列表会影响旧列表 class LanguageItemArrayAdapter extends ArrayAdapter<com.anysoftkeyboard.ui.settings.Languag

我通过适配器的add和clear从适配器对象中添加和删除值,它们正在将元素删除和添加到列表中,而该列表不会从适配器内的任何位置引用。我有一个orig列表,它位于适配器外部,有一个从适配器内部到未更改外部引用的引用,在适配器内部,我只引用了一个新列表,我使用旧的原始列表填充了相同的对象。为什么新列表会影响旧列表

class LanguageItemArrayAdapter extends ArrayAdapter<com.anysoftkeyboard.ui.settings.LanguageItem>{
    private Context mContext;
    private final ArrayList<com.anysoftkeyboard.ui.settings.LanguageItem> origList = new ArrayList<com.anysoftkeyboard.ui.settings.LanguageItem>();
    private final ArrayList<com.anysoftkeyboard.ui.settings.LanguageItem> filteredList = new ArrayList<com.anysoftkeyboard.ui.settings.LanguageItem>();

    LanguageItemArrayAdapter(@NonNull Context context, @LayoutRes ArrayList<com.anysoftkeyboard.ui.settings.LanguageItem> list, ArrayList<com.anysoftkeyboard.ui.settings.LanguageItem> filteredList){
        super(context, 0, filteredList);
        mContext = context;
        origList.addAll(list); //THIS WORKS WELL. 
        //THIS BREAKS EVERYTHING -> 
        //origlist = list;
    }

    public void fillData(){
        filteredList.addAll(origList);
        notifyDataSetChanged();

    }

    @Override
    public View getView(int position,  View convertView, @NonNull ViewGroup parent) {
        View listItem = convertView;
        if (listItem == null)
            listItem = LayoutInflater.from(mContext).inflate(R.layout.languages_list_row, parent, false);
        com.anysoftkeyboard.ui.settings.LanguageItem currentItem = filteredList.get(position);

        TextView title = listItem.findViewById(R.id.title);
        title.setText(currentItem.getTitle());

        return listItem;
    }

    private Filter myFilter = new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults filterResults = new FilterResults();
            ArrayList<com.anysoftkeyboard.ui.settings.LanguageItem> tempList=new ArrayList<com.anysoftkeyboard.ui.settings.LanguageItem>();
            //constraint is the result from text you want to filter against.
            //objects is your data set you will filter from
            if(constraint != null) {
                int length= origList.size();
                int i=0;
                while(i<length){
                    LanguageItem item= origList.get(i);
                    if(item.toString().toUpperCase().contains(constraint.toString().toUpperCase())) {
                        tempList.add(item);
                    }
                    i++;
                }
                //following two lines is very important
                //as publish result can only take FilterResults objects
                filterResults.values = tempList;
                filterResults.count = tempList.size();
            }

            return filterResults;
        }

        //HERE ARE THE AFFECTING METHODS:
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            filteredList.clear();

            clear(); //******THIS METHOD REMOVES THE VALUES from origList as well******
            filteredList.addAll((Collection<? extends LanguageItem>) results.values);
            notifyDataSetChanged();

            //*****THIS ADDS VALUES TO ORIG LIST AS WELL. WHY?*****
            for(LanguageItem item: filteredList)
                add(item); 

        }
    };

    @Override
    public Filter getFilter() {
        return myFilter;
    }
}
为什么原始列表会被编辑,而我只更改过滤后的列表

编辑:


我知道修复程序,我不明白原因-如果您像我一样在自定义适配器筛选器中遇到问题,修复程序在下面的代码中

此代码将ArrayList的相同实例传递给LanguageItemArrayAdapter

新的LanguageItemArrayAdaptergetContext,simpleLanguageItems,simpleLanguageItems 要理解为什么在ArrayAdapter中添加…和清除也会修改相同的对象,您需要从中查看它们的实现

公共空间已清理{ 同步锁定{ 如果mOriginalValues!=null{ mOriginalValues.clear; }否则{ mObjects.clear; } … } … } clear将修改mObjects和MoriginalValue您会注意到ArrayAdapter中的其他函数也会这样做。您需要阅读ArrayFilter中的代码,以了解它们是如何修改的

private class ArrayFilter extends Filter {
  /* 
  mObjects will contain only items fulfilling the filter conditions. 
  Original items are copied into mOriginalValues 
  */
}
查看构造函数和构造函数链,您会发现类构造函数

超级上下文,0,filteredList; 那最后会给你打电话

私有的ArrayAdapter@NonNull语境, @内部资源布局, @IdRes int textViewResourceId, @非空列表对象, 布尔对象资源{ … mObjects=对象; … }
这允许ArrayAdapter修改您的simpleLanguageItems实例。

在构造函数中,我会想到这个。filteredList=filteredList;或者最好删除字段filteredList,因为它似乎是父类。代码似乎有点值得重新设计。@Joop Eggen如果你知道答案,请告诉我,如果需要,我会重新编写、编译并编辑它。你能分享一下如何构造参数列表和过滤器列表的代码,以及如何调用LanguageItemArrayAdapter构造函数吗?@VitaliPom对不起,我太困惑了。我不一定比你强。@Joop♥ 酷,对不起。我有2-3个机器人投票否决我在这里写的每一个问题,今天又发生了。我还以为是他们中的一个。对不起,是的,代码有点脏,需要清理。同时,总的来说没关系,因为问题很有趣。我再次道歉,我发现好人很少。是的,当我在回购协议中修复时,我也会在这里修复。非常感谢你!!!!你是我的英雄!
private class ArrayFilter extends Filter {
  /* 
  mObjects will contain only items fulfilling the filter conditions. 
  Original items are copied into mOriginalValues 
  */
}