如何确保在解析数组时不返回重复的JSON数据?

时间:2019-01-07 15:20:21

标签: android arrays json parsing duplicates

几天前,我问了一个有关解析JSON数组的问题:

How do you parse a JSON Array w/o a defined array?

我正在下载11个项目的列表(由RecyclerView LinearLayoutManager在活动中以垂直布局显示)。由于某些原因,正在下载两个相同的列表。我仔细检查了Postman中测试Url的JSON数据,没有重复的值。此外,该API没有分页参数。

致主持人。我在这里发现了一些有关JSON中重复值的线程。同样,我的值中没有重复的值。预先谢谢你。

Remove Duplicate objects from JSON Array

remove duplicate values from json data

来自上述线程的

JSONUtils类:

public class JSONUtils
{
    /**
     * Tag for the log messages
     */
    private static final String LOG_TAG = JSONUtils.class.getSimpleName();

    private static final String KEY_LINE_ID = "id";
    private static final String KEY_LINE_NAME = "name";


    public JSONUtils()
    {
    }

    public static Lines extractFeatureFromJson (String linesJSON)
    {
        // If the JSON string is empty or null, then return early.
        if (TextUtils.isEmpty(linesJSON)) {
            return null;
        }

        Lines line = null;
        try
        {
            // Create a JSONObject from the JSON file
            JSONObject jsonObject = new JSONObject(linesJSON);

            String id = "";
            if (jsonObject.has("id"))
            {
                id = jsonObject.optString(KEY_LINE_ID);
            }


            String name = "";
            if (jsonObject.has("name"))
            {
                name= jsonObject.optString(KEY_LINE_NAME);
            }

            line = new Lines(id, name);
    }
        catch (JSONException e)
    {
        // If an error is thrown when executing any of the above statements in the "try" block,
        // catch the exception here, so the app doesn't crash. Print a log message
        // with the message from the exception.
        Log.e("QueryUtils", "Problem parsing lines JSON results", e);

    }
        // Return the list of lines
        return line;
}
}

RecyclerViewAdapter类:

public class LinesAdapter extends RecyclerView.Adapter<LinesAdapter.LinesAdapterViewHolder>
{
    private static final String TAG = LinesAdapter.class.getSimpleName();

    private ArrayList<Lines> linesList = new ArrayList<Lines>();
    private Context context;
    private LinesAdapterOnClickHandler mLineClickHandler;

    /**
     * The interface that receives onClick messages.
     */
    public interface LinesAdapterOnClickHandler
    {
        void onClick(Lines textLineClick);
    }

    /**
     * Creates a Lines Adapter.
     *
     *  @param lineClickHandler The on-click handler for this adapter. This single handler is called
     *      *                     when an item is clicked.
     */
    public LinesAdapter(LinesAdapterOnClickHandler lineClickHandler, ArrayList<Lines> linesList, Context context)
    {
        mLineClickHandler = lineClickHandler;
        this.linesList = linesList;
        this.context = context;
    }

    /**
     * Cache of the children views for a line list item.
     */
    public class LinesAdapterViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
    {
        @BindView(R.id.line_name)
        public TextView lineName;

        public LinesAdapterViewHolder(View view)
        {
            super(view);
            ButterKnife.bind(this, view);
            view.setOnClickListener(this);
        }

        /**
         * This gets called by the child views during a click.
         *
         * @param v The View that was clicked
         */
        @Override
        public void onClick(View v)
        {
            int adapterPosition = getAdapterPosition();
            Lines textLineClick = linesList.get(adapterPosition);
            mLineClickHandler.onClick(textLineClick);
        }
    }

    @Override
    public LinesAdapterViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType)
    {
        Context context = viewGroup.getContext();
        int layoutIdForListItem = R.layout.line_list_item;
        LayoutInflater inflater = LayoutInflater.from(context);
        boolean shouldAttachToParentImmediately = false;
        View view = inflater.inflate(layoutIdForListItem, viewGroup, shouldAttachToParentImmediately);
        return new LinesAdapterViewHolder(view);
    }

    /**
     * Cache of the children views for a line list item.
     */
    @Override
    public void onBindViewHolder(LinesAdapterViewHolder holder, int position)
    {
        //Binding data
        final Lines lineView = linesList.get(position);

        holder.lineName.setText(lineView.getLineName());
    }

    @Override
    public int getItemCount()
    {
        return linesList.size();
    }

    public void setLinesList(ArrayList<Lines> mLinesList)
    {
        this.linesList.addAll(mLinesList);
        notifyDataSetChanged();
    }
}

1 个答案:

答案 0 :(得分:1)

此方法看起来可疑:

public void setLinesList(ArrayList<Lines> mLinesList)
{
    this.linesList.addAll(mLinesList);
    notifyDataSetChanged();
}

它的名称类似于“ setter”,但实际上不是设置行,而是添加行。如果您的代码使用相同的参数两次调用了此代码,那么最终将出现重复项。

有两种编写此方法的方法,这样它每次实际上都会覆盖列表:

public void setLinesList(ArrayList<Lines> mLinesList)
{
    this.linesList.clear();
    this.linesList.addAll(mLinesList);
    notifyDataSetChanged();
}
public void setLinesList(ArrayList<Lines> mLinesList)
{
    this.linesList = new ArrayList<>(mLinesList);
    notifyDataSetChanged();
}