HashSet行为令人惊讶

时间:2018-04-13 10:04:59

标签: java android hashset

我在stackoverflow上搜索了这个,发现了这种情况的无关线程。我也尝试了自己,并将继续尝试,直到解决方案。但如果有人告诉我,如果我在代码中犯了任何错误,那将会很好。

我有一个HashSet,这样我就可以防止重复的字符串被添加到其中。如果HashSet正在添加,那么它必须是唯一的字符串。

我的班级声明是:

public List<String> ContactsList;
public List<String> ContactsNumbersList;

我的代码通过HashSet的帮助获取联系人并将其添加到这两个列表中,以便我保留重复的数字:

    ContactsList = new ArrayList<String>();
    ContactsNumbersList = new ArrayList<String>();

    HashSet<String> normalizedNumbersAlreadyFound = new HashSet<>();

    // Contacts Database queries

    Cursor cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, new String[] {ContactsContract.CommonDataKinds.Phone._ID, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER}, null, null,  ContactsContract.CommonDataKinds.Phone.SORT_KEY_PRIMARY +" ASC");


    while (cursor.moveToNext())
    {
        String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
        String phoneNumber = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));

        if (normalizedNumbersAlreadyFound.add(phoneNumber))
        {
            phoneNumber = phoneNumber.replace("-","");
            phoneNumber = phoneNumber.replace(" ","");
            phoneNumber = phoneNumber.replace("(","");
            phoneNumber = phoneNumber.replace(")","");
            ContactsList.add(name);
            ContactsNumbersList.add(phoneNumber);
        }

    }
    cursor.close();

那么为什么我的ContactsNumbersList有重复的条目...?提前感谢您的任何建议..这将有助于我。

1 个答案:

答案 0 :(得分:9)

您的设计似乎存在问题。

首先,如果你的目标是使用没有重复的集合,那么你不需要List

只需使用您的Set即可。

其次,特别是对您的代码,您正在检查该元素是否已添加到Set 规范化之前,并将规范化的String添加到{{1 }}。

因此,很可能您的List将包含重复项,因为在规范化之前,两个在规范化之前不同的元素可能相等。

这让我回过头来建议您直接使用List,并在此用例中忽略使用Set

示例

List

<强>输出

List<String> source = Arrays.asList("123-456789", "(1)23456789");
System.out.printf("Source List contains: %s%n", source);
Set<String> set = new HashSet<>();
List<String> unnecessary = new ArrayList<>();
Set<String> useful = new HashSet<>();

for (String s: source) {
    if (set.add(s)) System.out.printf("Added %s to set.%n", s);
    s = s.replaceAll("[()-]", "");
    System.out.printf("\t... now normalized to %s%n", s);
    // s is now normalized
    unnecessary.add(s);
    useful.add(s);
}
System.out.printf(
    "Set contains %s.%nUnnecessary List contains %s.%nUseful Set contains %s.%n", 
    set, 
    unnecessary,
    useful
);