0

I have created a custom ContactsRow class containing three variables. I am adding objects of this class to ArrayList one-by-one. What I want to achieve is that, whenever I add new object to ArrayList, it should check if that object is already added to the list. I am using contains() method to check the same. However, when I run my app, this method is never called and I am getting duplicate values in the list.

Here is my ContactsRow class:

private class ContactsRow {

        String name, phone;
        Bitmap photo;

        @Override
        public boolean equals(Object obj) {

            if (this == obj)
                return true;

            if ((obj == null) || (obj.getClass() != this.getClass()))
                return false;

            ContactsRow row = (ContactsRow) obj;
            return (name.equals(row.name) || (name != null && name.equals(row.name))) &&
                    (phone.equals(row.phone)  || (phone != null && phone.equals(row.phone))) &&
                    (photo.equals(row.photo) || (photo != null && photo.equals(row.photo)));
        }

        @Override
        public int hashCode() {
            int hash = 7;
            hash = 31 * hash + (name == null ? 0 : name.hashCode());
            hash = 31 * hash + (phone == null ? 0 : phone.hashCode());
            hash = 31 * hash + (photo == null ? 0 : photo.hashCode());

            return hash;
        }

        public ContactsRow(String name, String phone, Bitmap photo) {
            this.name = name;
            this.phone = phone;
            this.photo = photo;
        }
    }

Here is how I am adding and checking values in ArrayList:

contactsRow = new ContactsRow(contactName, contactNumber, contact_Photo);

                    if(contactsRowList.contains(contactsRow)){

                        AlertDialog.Builder duplicateBuilder = new AlertDialog.Builder(MyContactsActivity.this);
                        duplicateBuilder.setTitle("Duplicate contact");
                        duplicateBuilder.setMessage("This contact is already added to list. Please choose unique contact");
                        duplicateBuilder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {

                                Intent intent = new Intent(Intent.ACTION_PICK);
                                intent.setType(ContactsContract.Contacts.CONTENT_TYPE);
                                startActivityForResult(intent, REQUEST_CONTACT);
                                duplicateEntryDialog.dismiss();
                            }
                        });
                        duplicateEntryDialog = duplicateBuilder.create();
                        duplicateEntryDialog.show();

                    } else {
                        contactsRowList.add(contactsRow);
                        contactsInfoAdapter.notifyDataSetChanged();
                    }

This AlertDialog is never called.

Can anyone help me identify the issue????

Vaibhav Agarwal
  • 975
  • 1
  • 7
  • 22
  • 1
    If you need to disallow duplicate values in your collection, then Set is the way to go. – Tomasz Nocoń Aug 14 '16 at 16:53
  • @TomaszNocoń I will try to do that. Can you tell if I have implemented above code correctly, especially `equals()` and `hashcode()` methods??? – Vaibhav Agarwal Aug 14 '16 at 16:58
  • "However, when I run my app, this method is never called". How do you know that `contains` is never called? Also, your `equals` implementation is messed up. Example : checking `name != null` is pointless when the previous statement itself will fail if name is null. – Chetan Kinger Aug 14 '16 at 16:59
  • I am adding `objects` to `ArrayList` and using that list to display custom rows in `ListView`. When I add same contact twice, it is added twice to the `ListView`. That is how I came to know it. @CKing – Vaibhav Agarwal Aug 14 '16 at 17:02
  • Your equals doesnt really have sane null handling, but is fine enough to either cause an npe or make .contains work. So `.equals` is not your problem. What does the debugger say, are there actually objects in your list? – k5_ Aug 14 '16 at 17:02
  • yes. objects are present in the list. That is why `ListView` displays it more than once. @k5_ – Vaibhav Agarwal Aug 14 '16 at 17:03
  • @VaibhavAgarwal But how does that prove that the `contains` method is not called? It's quite possible that the method in which you call `contains` itself is not called in the first place or that your `equals` implementation is messed up. How does the fact that the code is not doing what it is supposed to imply that it must be because of `contains` not getting called? – Chetan Kinger Aug 14 '16 at 17:04
  • The problem is the usage of `Bitmap.equals`. http://stackoverflow.com/questions/6120439/comparing-bitmap-images-in-android seems to be one approach. – k5_ Aug 14 '16 at 17:06
  • @CKing method in which I call `contains` is being called. If you see above mentioned code, I have used `if-else` block. `else` part of that block is always called and object is added to the `ArrayList` and thus is displayed in the `ListView`. However, `if` part of the block is not being called when I add same object. – Vaibhav Agarwal Aug 14 '16 at 17:09
  • I have implemented `equals` from this http://www.technofundo.com/tech/java/equalhash.html – Vaibhav Agarwal Aug 14 '16 at 17:14
  • Problem solved guys!!! Using the link posted by @k5_, I have changed `Bitmap.equals` to `Bitmap.sameAs` and now my code works fine!!! The only problem that is left is if two object that are being compared have `null` value in `Bitmap` variable, `(photo.sameAs(row.photo) || (photo != null && photo.sameAs(row.photo)));` is throwing `NullPointerException`. Can any help me with this as well?? – Vaibhav Agarwal Aug 14 '16 at 17:18
  • Remove the first part, `photo.equals(row.photo) ||`, keep only `photo != null && photo.equals(row.photo)`. It really doesn't make sense to see if `photo` equals `row.photo` and then see if `photo` is not `null` and `photo` equals `row.photo`. It makes your `null` check useless. – Arjan Aug 14 '16 at 17:32
  • @Arjan I tried doing that. However, now when two objects, both having `Bitmap == null` are compared, `contains` method is not being called. Is there any other way out??? – Vaibhav Agarwal Aug 14 '16 at 17:41
  • Hey, I have been able to solve `NullpointerException` problem by creating one more `constructor` in `ContactsRow` class with only two args `name` and `phone`, and then checked `if(photo == null)` both while creating the object and under `equals` method. Thanks a ton guys for helping me out. You all saved my day!!!!! – Vaibhav Agarwal Aug 14 '16 at 18:00

0 Answers0