Как убедиться, что дублирующиеся данные JSON не возвращаются при разборе массива? - PullRequest
0 голосов
/ 07 января 2019

Я задал вопрос о разборе массива JSON пару дней назад:

Как анализировать массив JSON без определенного массива?

Я загружаю список из 11 элементов (отображается в вертикальной компоновке в упражнении с помощью RecyclerView LinearLayoutManager). По какой-то причине загружаются два одинаковых списка. Я дважды проверил данные JSON, проверил URL в Postman, и нет повторяющихся значений. Кроме того, API не имеет параметра пагинации.

Модератору. Я нашел несколько тем здесь о повторяющихся значениях в JSON. Опять же, у меня нет повторяющихся значений. Заранее спасибо.

Удалить дубликаты объектов из массива JSON

удалить повторяющиеся значения из данных json

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 голосов
/ 08 января 2019

Этот метод выглядит подозрительно:

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

У него есть имя, похожее на «сеттер», но на самом деле это не настройка строк, это добавление строк. Если бы у вас был код, который вызывал это дважды с одинаковыми аргументами, вы бы получили дубликаты.

Вот два способа написания этого метода, чтобы он фактически перезаписывал список каждый раз:

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