Java 集合是否接受重复的 String[]?
Do Java Sets accept duplicate String[]?
在我的 Android 应用程序中,我使用查询来获取 phone 中的所有联系人。我知道这可能会导致重复元素,所以我使用 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
接受重复元素?如何解决这个问题?
String[] 没有 LinkedHashSet
期望保持唯一性的 hashCode()
和 equals
语义。
为了快速修复,请尝试使用 ArrayList<String>
而不是 String[]
,它确实定义了这些方法。
编辑 - 您可以使用以下习惯用法代替 moveToFirst
:
来简化对游标结果的迭代
while (cursor.moveToNext()) {
// .. use the cursor
}
这是可行的,因为游标语义保证游标将放置在第一个结果(如果有)之前,并且如果没有要移动到的行的下一个值,则return false。
使用 LinkedHashSet<String[]>
不是一个好主意,因为 LinkedHashSet
通过调用 equals
检查重复项,而 String[]
的 equals()
只使用 ==
。这意味着 new String[] {"12345", "Joe"}
和 new String[] {"12345", "Joe"}
不被视为相等。
相反,您应该定义一个名为 Contact
的 class,如下所示:
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();
}
}
那你就可以使用LinkedHashSet<Contact>
.
在我的 Android 应用程序中,我使用查询来获取 phone 中的所有联系人。我知道这可能会导致重复元素,所以我使用 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
接受重复元素?如何解决这个问题?
String[] 没有 LinkedHashSet
期望保持唯一性的 hashCode()
和 equals
语义。
为了快速修复,请尝试使用 ArrayList<String>
而不是 String[]
,它确实定义了这些方法。
编辑 - 您可以使用以下习惯用法代替 moveToFirst
:
while (cursor.moveToNext()) {
// .. use the cursor
}
这是可行的,因为游标语义保证游标将放置在第一个结果(如果有)之前,并且如果没有要移动到的行的下一个值,则return false。
使用 LinkedHashSet<String[]>
不是一个好主意,因为 LinkedHashSet
通过调用 equals
检查重复项,而 String[]
的 equals()
只使用 ==
。这意味着 new String[] {"12345", "Joe"}
和 new String[] {"12345", "Joe"}
不被视为相等。
相反,您应该定义一个名为 Contact
的 class,如下所示:
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();
}
}
那你就可以使用LinkedHashSet<Contact>
.