2

I am trying to get unique phone numbers from the contact provider in android and I am using a HashSet to add the different phone numbers of a contact

   Set<String> newNumbers = new HashSet<>();

   while(findNumbers.moveToNext()){
      String phone = findNumbers.getString(0);
      phone = phone.replaceAll("[\\s\\-()]", ""); 
      boolean isNumberAdded = newNumbers.add(phone);
      if(isNumberAdded){
         Log.d(TAG,"Phone= " + phone);
       }else{
         Log.d(TAG,"Rejected Phone= " + phone);
         continue;
        }
    }

However this happens:

  1. Phone= 0502809903
  2. Phone= ‪+971556072980‬
  3. Rejected Phone= ‪+971556072980‬ <- rejected duplicate
  4. Phone= +971552767944
  5. Phone= +971556072980 <-- accepted duplicate

EDIT: If the Strings are created like this, it works however the strings that I get from the cursor does not.

    ArrayList<String> testing = new ArrayList<String>();
    testing.add("0502809903");
    testing.add("+971556072980");
    testing.add("+971556072980");
    testing.add("+971552767944");
    testing.add("+971556072980");

    Set<String> numbers = new HashSet<>();
    for(String data: testing){

        boolean isNumberAdded = numbers.add(data);
        if(isNumberAdded){
            Log.d("Test","Accepted " + data);
        }else{
            Log.d("Test","Rejected " + data);
        }
    }

Edit2: displayed the numbers as char arrays, How do I fix it?

  1. Original = [0, 5, 0, 2, 8, 0, 9, 9, 0, 3]
  2. Accepted Phone= 0502809903
  3. Original = [‪, +, 9, 7, 1, 5, 5, 6, 0, 7, 2, 9, 8, 0, ‬]
  4. Accepted Phone= ‪+971556072980‬
  5. Original = [‪, +, 9, 7, 1, 5, 5, 6, 0, 7, 2, 9, 8, 0, ‬]
  6. Rejected Phone= ‪+971556072980‬
  7. Original = [+, 9, 7, 1, 5, 5, 2, 7, 6, 7, 9, 4, 4]
  8. Accepted Phone= +971552767944
  9. Original = [+, 9, 7, 1, 5, 5, 6, 0, 7, 2, 9, 8, 0]
  10. Accepted Phone= +971556072980
androiduae
  • 153
  • 2
  • 9
  • Could you please show us the creation of newNumbers object? I'm interested what type does it have. – astrohome Sep 03 '15 at 12:05
  • Are you saying that the first time you add to the set the number is rejected and the second time you add it it is accepted? Or is the first one being overridden with the second? – Nicholas Robinson Sep 03 '15 at 12:09
  • it works 90% of the time, this is the 10%.... – androiduae Sep 03 '15 at 12:11
  • You are missing some code. In your current code you create a HashSet, add a single element to it, and then suddenly the code ends. There's no way you could get your output without a loop somewhere. You should provide the looping code because the bug is probably not in the code you posted, but something to do with how you are looping and storing variables over multiple iterations. – Mark Byers Sep 03 '15 at 12:13
  • addded loop and hashset object – androiduae Sep 03 '15 at 12:27
  • If you add the numbers from a predefined `Set` instead of wherever they are coming from now, do you still get the same behavior? – Keppil Sep 03 '15 at 12:50
  • it worked in a predefined set but why doesn't it work here – androiduae Sep 03 '15 at 13:13
  • 1
    Great, you have isolated the problem. The strings from the cursor contain something that your example strings don't. Examine those strings more carefully, and you should find the error. – Keppil Sep 03 '15 at 14:06
  • for me here doesn't work because you're passing "wired" string constants. This will work or not depending on String pool, which you can't control. – Shine Sep 03 '15 at 15:45

2 Answers2

1

You have garbage in your strings. Try this:

boolean isNumberAdded = newNumbers.add(phone.trim());

This should do the trick.

EDIT: Or maybe it doesn't... According to this question, if you want to remove non-printable characters, you should use the following:

boolean isNumberAdded = newNumbers.add(phone.replaceAll("\\p{C}", ""));

Let me know if it works this time.

Community
  • 1
  • 1
fps
  • 33,623
  • 8
  • 55
  • 110
-2

HashSet will use GetHashCode and Equals to determine equality of your objects. Right now, since you're not overriding these methods , the default System.Object's reference equality will be used. Each time you add a new value, it's a unique object instance, so the HashSet sees it as a unique object.

you will need to override hashcode and equal.

Why is it important to override GetHashCode when Equals method is overridden?

Community
  • 1
  • 1
amit dayama
  • 3,246
  • 2
  • 17
  • 28
  • if its set to false, it means the value was not added right? – androiduae Sep 03 '15 at 12:16
  • 2
    I have to override String object...? – androiduae Sep 03 '15 at 12:47
  • 2
    You can't ovverride anything from the `String` class, it is final. This answer is completely wrong. – Keppil Sep 03 '15 at 12:52
  • the answer is conceptually correct, but of course you can't override String's equals() and hashCode(). Just create a Serializable POJO with a String inside, override the two methods and you're done – Shine Sep 03 '15 at 15:37