【问题标题】:How to make sure that duplicate JSON data isn't being returned when parsing an array?如何确保在解析数组时不返回重复的 JSON 数据?
【发布时间】:2019-06-02 06:40:48
【问题描述】:

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

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

我正在下载 11 个项目的列表(在 RecyclerView LinearLayoutManager 的活动中以垂直布局显示)。出于某种原因,正在下载两个相同的列表。我仔细检查了 JSON 数据在 Postman 中测试了 Url,并且没有重复值。此外,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();
    }
}

【问题讨论】:

  • 你能分享你的代码吗?
  • @HousseinZouariCode 添加。谢谢。
  • 我感觉你的方法被执行了两次或更多次。你能分享一下你实现列表的代码吗?
  • @LeadBox4,显示您将数据添加到 ArrayList 的代码。
  • @RakeshKumar@Houssein Zouari,代码中添加了操作。再次感谢您。

标签: android arrays json parsing duplicates


【解决方案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();
}

【讨论】:

  • 解决了!感谢您的代码示例。我做的有点不同:this.linesList = mLinesList; notifyDataSetChanged();
  • 太好了,很高兴为您提供帮助!如果您觉得这很有用,请考虑投票和/或接受答案,以便其他访问者可以看到它对您有用。评论可以随时删除。
  • 不幸的是,我没有足够的积分来投票。也许其中一位版主可以做到。只要我有资格这样做,我就会投票赞成。再次感谢您。
猜你喜欢
  • 2020-12-04
  • 2021-01-17
  • 1970-01-01
  • 1970-01-01
  • 2013-04-05
  • 1970-01-01
  • 2020-03-04
  • 2015-05-01
  • 1970-01-01
相关资源
最近更新 更多