【问题标题】:HashSet behaviour is surprisingHashSet 的行为令人惊讶
【发布时间】:2018-04-13 10:04:58
【问题描述】:

我在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 有重复的条目...?提前感谢您的任何建议..这将对我有所帮助。

【问题讨论】:

  • 在确保原始字符串不存在后替换一些字符。可能是原因。另外,为什么不直接在一个Set中添加元素,然后用它来构建一个列表呢?
  • 可能是因为您在将电话号码添加到normalizedNumbersAlreadyFound 集合之后 删除了垃圾。尝试在检查之前进行清理。

标签: java android hashset


【解决方案1】:

您的设计似乎有问题。

首先,如果您的目标是使用没有重复的集合,则不需要Lists。

请改用您的Set

其次,特别是对于您的代码,您正在检查该元素是否已添加到您的 Set 规范化它并将规范化的 String 添加到 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
);

输出

Source List contains: [123-456789, (1)23456789]
Added 123-456789 to set.
    ... now normalized to 123456789
Added (1)23456789 to set.
    ... now normalized to 123456789
Set contains [(1)23456789, 123-456789].
Unnecessary List contains [123456789, 123456789].
Useful Set contains [123456789].

【讨论】:

  • 正要写一个类似的答案,而你的答案已经弹出。 +1 速度和完整性。
  • @Mena,点赞。我的错误...我放错了代码...是的,您指出的如此准确...需要投票
猜你喜欢
  • 2019-10-05
  • 2021-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-27
  • 2015-10-19
  • 2012-08-11
  • 1970-01-01
相关资源
最近更新 更多