【问题标题】:Getting duplicate Elements using HashSet使用 HashSet 获取重复元素
【发布时间】:2015-06-05 11:32:32
【问题描述】:

我正在使用 ArrayList 填充和 HashSet 删除重复元素的 ListView 中的重复条目,但仍然得到这样的重复值:

Delhi
Mumbai
Delhi
Mumbai

这是我用来将 JSON 数据解析为 List 并删除重复条目的代码

MainActivity.java:

public class MainActivity extends Activity {

    ArrayList<Destination> destinationArrayList;    
    MainAdapter adapter;
    Destination destination;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        destinationArrayList = new ArrayList<Destination>();

        new JSONAsyncTask().execute("my api link");

        Set<Destination> hashset = new HashSet<>(); 
        hashset.addAll(destinationArrayList); 
        destinationArrayList.clear(); 
        destinationArrayList.addAll(hashset);

        ListView listview = (ListView)findViewById(R.id.list);
        adapter = new MainAdapter(getApplicationContext(), R.layout.row, destinationArrayList);

        listview.setAdapter(adapter);

        listview.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int position,
                    long id) {
                // TODO Auto-generated method stub
                Toast.makeText(getApplicationContext(), destinationArrayList.get(position).getTitle().toString(), Toast.LENGTH_LONG).show();                
            }
        });

    }


    class JSONAsyncTask extends AsyncTask<String, Void, Boolean> {

        ProgressDialog dialog;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            dialog = new ProgressDialog(MainActivity.this);
            dialog.setMessage("Loading, please wait");
            dialog.show();
            dialog.setCancelable(false);
        }

        @Override
        protected Boolean doInBackground(String... urls) {
            try {

                //------------------>>
                HttpGet httppost = new HttpGet(urls[0]);
                HttpClient httpclient = new DefaultHttpClient();
                HttpResponse response = httpclient.execute(httppost);

                // StatusLine stat = response.getStatusLine();
                int status = response.getStatusLine().getStatusCode();

                if (status == 200) {
                    HttpEntity entity = response.getEntity();
                    String data = EntityUtils.toString(entity);


                    JSONObject jsono = new JSONObject(data);
                    JSONArray jarray = jsono.getJSONArray("data");

                    for (int i = 0; i < jarray.length(); i++) {
                        JSONObject object = jarray.getJSONObject(i);

                        destination = new Destination();

                        destination.setCity(object.getString("city"));

                        destinationArrayList.add(destination);

                    }
                    return true;
                }

                //------------------>>

            } catch (ParseException e1) {
                e1.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return false;
        }

        protected void onPostExecute(Boolean result) {
            dialog.cancel();
            adapter.notifyDataSetChanged();
            if(result == false)
                Toast.makeText(getApplicationContext(), "Unable to fetch data from server", Toast.LENGTH_LONG).show();

        }
    }

}

当我使用这个时,甚至not getting single record 进入 ListView:

destinationArrayList = new ArrayList<Destination>();

        new JSONAsyncTask().execute("my api url");

        System.out.println("size of Arraylist with duplicates: " + destinationArrayList.size());

        System.out.println(destinationArrayList);

        HashSet<Destination> listToSet = new HashSet<Destination>(destinationArrayList);

        ArrayList<Destination> listWithoutDuplicates = new ArrayList<Destination>(listToSet);
        System.out.println("size of ArrayList without duplicates: " + listToSet.size());

        System.out.println(listWithoutDuplicates);

Destination.java

public class Destination {

    private String city;
    ..............

    public Destination() {
        // TODO Auto-generated constructor stub
    }

    public Destination(String city) {
        super();
        this.city = city;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

}

【问题讨论】:

标签: java android arraylist hashset


【解决方案1】:

您将 Custom objects 放入 HashSet,因此它不会消除重复项。您需要覆盖目标对象的equalshashCode。然后就可以正常使用了。

class Destination {

    private String city;

    public Destination() {
        // TODO Auto-generated constructor stub
    }

    public Destination(String city) {
        super();
        this.city = city;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Destination that = (Destination) o;

        if (city != null ? !city.equals(that.city) : that.city != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        return city != null ? city.hashCode() : 0;
    }
}

将此代码放在 AsynTask 中的 postExecute() 方法中,然后它会显示列表中的所有元素。

 Set<Destination> hashset = new HashSet<>(); 
        hashset.addAll(destinationArrayList); 
        destinationArrayList.clear(); 
        destinationArrayList.addAll(hashset);

        ListView listview = (ListView)findViewById(R.id.list);
        adapter = new MainAdapter(getApplicationContext(), R.layout.row, destinationArrayList);

        listview.setAdapter(adapter);

【讨论】:

  • 用你的方式更新了 Destination java 类,但还没有完成
  • @Oreo 您需要在 AsynTask 完成后设置值。
  • @Oreo 如果您需要排序实现可比较并使用 Collections.sort(list);并且您使用 AsyncTask,因此无法将您的代码放入 onCreate()。
【解决方案2】:

使用Set 的重复数据删除不起作用,因为根据您当前的Destination 类定义,具有相同city 值的Destination 实例不被视为相等。

Destination 类中尝试 overriding .equals....

【讨论】:

    【解决方案3】:

    我敢打赌,散列集无法将两对 Destination 对象识别为相等,无论它们只有一个属性 City

    要比较两个对象,您需要覆盖超级方法equals,并且您的对象被用于哈希表,您还需要覆盖hashCode

    有一些行之有效的方法可以避免您可以在hashCode 中使用的哈希冲突。其中之一是Best implementation for hashCode method

    【讨论】:

      【解决方案4】:

      您的 Destination 类应该有 equals() 和 hashCode() 方法来消除与城市的重复记录。以下包含方法的代码可以解决您的问题:

      public class Destination {
      
          private String city;
          ..............
      
          @Override
          public int hashCode() {
              final int prime = 31;
              int result = 1;
              result = prime * result + ((city == null) ? 0 : city.hashCode());
              return result;
          }
      
          @Override
          public boolean equals(Object obj) {
              if (this == obj)
                  return true;
              if (obj == null)
                  return false;
              if (getClass() != obj.getClass())
                  return false;
              Destination other = (Destination) obj;
              if (city == null) {
                  if (other.city != null)
                      return false;
              } else if (!city.equals(other.city))
                  return false;
              return true;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-03-29
        • 2022-07-05
        • 2015-07-28
        • 2015-06-22
        • 1970-01-01
        • 2021-07-16
        • 2018-06-09
        • 1970-01-01
        相关资源
        最近更新 更多