在我的Android应用中,我使用查询来获取手机中的所有联系人。我知道这可能导致重复的元素,所以我使用LinkedHashSet
来处理它:
private void retrieveContacts(ContentResolver contentResolver) {
LinkedHashSet<String[]> contactSet = new LinkedHashSet<String[]>();
final Cursor cursor = contentResolver.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
new String[] {
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER }, null,
null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
if (cursor == null);
if (cursor.moveToFirst() == true) {
do {
final String name = cursor
.getString(cursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
final String telephone = cursor
.getString(cursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)).replace(" ", "").replace("+336", "06");
String[] contactString = {telephone, name};
contactSet.add(contactString);
} while (cursor.moveToNext() == true);
}
if (cursor.isClosed() == false) {
cursor.close();
}
for (String[] contactString : contactSet){
Contact contact = new Contact(contactString[0], contactString[1], false, false);
daocontact.add(contact);
}
Contact
是我使用的Bean代表联系人,而daocontact是将联系人存储在数据库中的DAO。问题是,似乎Set实际存储了重复的元素,因为当我根据数据库的记录显示ListView时,它显示了许多重复的元素。
为什么Set
接受重复的元素?如何解决这个问题?
答案 0 :(得分:2)
String []没有hashCode()
和equals
语义,LinkedHashSet
期望保持唯一性。
要快速解决问题,请尝试使用ArrayList<String>
代替String[]
,而moveToFirst
会定义这些方法。
编辑 - 您可以使用以下惯用语而不是while (cursor.moveToNext()) {
// .. use the cursor
}
来简化对游标结果的迭代:
{{1}}
这是有效的,因为游标语义保证光标将被放置在第一个结果之前(如果有的话),如果没有下一个值要移动到行,则返回false。
答案 1 :(得分:2)
使用LinkedHashSet<String[]>
并不是一个好主意,因为LinkedHashSet
会通过调用equals
来检查重复项,而equals()
的{{1}}只会使用String[]
}}。这意味着==
和new String[] {"12345", "Joe"}
不被视为相等。
相反,您应该定义一个名为new String[] {"12345", "Joe"}
的类,如下所示:
Contact
然后您就可以使用public final class Contact {
private final String number;
private final String name;
public Contact(String number, String name) {
this.number = number;
this.name = name;
}
public String number() { return number; }
public String name() { return name; }
@Override
public boolean equals(Object object) {
if (object == this)
return true;
if (!(object instanceof Contact))
return false;
Contact that = (Contact) object;
return that.number.equals(number) && that.name.equals(name);
}
@Override
public int hashCode() {
return number.hashCode() ^ name.hashCode();
}
}
。