使用 HashSet 获取重复元素
Getting duplicate Elements using HashSet
我正在使用 ArrayList 填充和 HashSet 删除重复元素将重复条目添加到 ListView 中,但仍然会像这样获取重复值:
Delhi
Mumbai
Delhi
Mumbai
这是我用来将 JSON 数据解析到列表中并删除重复条目的代码
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;
}
}
使用 Set
的重复数据删除不起作用,因为根据您当前的 Destination
class 定义,Destination
的实例具有相同的 city
值不被认为是相等的。
在你的 Destination
class 中尝试 overriding .equals...
您将 Custom objects
放入 HashSet,因此它不会消除重复项。您需要覆盖目标对象的 equals
和 hashCode
。然后就正常了。
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
对象识别为相等,无论它们只有一个 属性 City
.
要比较两个对象,您需要覆盖超级方法 equals
并且您的对象正被用于哈希 table,您还需要覆盖 hashCode
有一些行之有效的方法可以避免哈希冲突,您可以在 hashCode
中使用这些方法。其中之一是 Best implementation for hashCode method
您的目的地 class 应该有 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;
}
}
我正在使用 ArrayList 填充和 HashSet 删除重复元素将重复条目添加到 ListView 中,但仍然会像这样获取重复值:
Delhi
Mumbai
Delhi
Mumbai
这是我用来将 JSON 数据解析到列表中并删除重复条目的代码
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;
}
}
使用 Set
的重复数据删除不起作用,因为根据您当前的 Destination
class 定义,Destination
的实例具有相同的 city
值不被认为是相等的。
在你的 Destination
class 中尝试 overriding .equals...
您将 Custom objects
放入 HashSet,因此它不会消除重复项。您需要覆盖目标对象的 equals
和 hashCode
。然后就正常了。
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
对象识别为相等,无论它们只有一个 属性 City
.
要比较两个对象,您需要覆盖超级方法 equals
并且您的对象正被用于哈希 table,您还需要覆盖 hashCode
有一些行之有效的方法可以避免哈希冲突,您可以在 hashCode
中使用这些方法。其中之一是 Best implementation for hashCode method
您的目的地 class 应该有 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;
}
}