Mr Chasi
Mr Chasi

Reputation: 437

Adding unique objects to ArrayList

I'm trying to create a basic mobile phone application. I'm trying (but failing) to implement a feature to query existing contacts on the phone. I have done this by creating a method which returns an ArrayList object containing contacts. This is supposed to work by searching (using a for loop) to see if a particular contact exists, and adding it to the ArrayList if so. Thereafter, the method should return an ArrayList object containing nothing but the results of the query. However, when testing my code, I find that EVERY contact is added to the ArrayList regardless of whether it matches the query or not. Here are some snippets of my code:

Phone.java

private ArrayList<Contact> contacts;

public Phone() {
    this.contacts = new ArrayList<>();
}

public ArrayList<Contact> queryContacts(String contactName) {
       ArrayList<Contact> contactsList = new ArrayList<>();

        for (Contact contact : this.contacts) {
            if (this.findContact(contactName)) 
                contactsList.add(contact);
        }
        return contactsList;
    }

    private boolean findContact(String contactName) {
            for (Contact contact : this.contacts) {
                if (contact.getName().equals(contactName))
                    return true;
            }
            return false;
}

Testing my code (Main.java)

public static void main(String[] args) {
        char c= 'A';

        for (int i = 0; i < 10; i++) {
            //Create contacts with unique data
            phone.addContact(Contact.createContact("Contact"+c++, "07"+i));
        }

        System.out.println(phone.queryContacts("VoidContact")); //Dubious entry
        System.out.println(phone.queryContacts("ContactB")); //This entry exists
    }

Rightfully so, I receive no output upon invoking the phone.queryContacts() method with the "VoidContact" parameter. However, upon invoking it with the legitimate parameter "ContactB", rather than just receiving just one contact, I get the following output (please note that I have overrided Object.toString() in my Contact class):

Name: 'ContactA' Number: 070
Name: 'ContactB' Number: 071
Name: 'ContactC' Number: 072
Name: 'ContactD' Number: 073
Name: 'ContactE' Number: 074
Name: 'ContactF' Number: 075
Name: 'ContactG' Number: 076
Name: 'ContactH' Number: 077
Name: 'ContactI' Number: 078
Name: 'ContactJ' Number: 079

My question; why is outputting every contact as opposed to the unique contacts based on the inputted parameters? Thanks much in advance for your respones.

Upvotes: 0

Views: 6861

Answers (2)

Victor1125
Victor1125

Reputation: 702

The best solution is use HashSet

Set<Contact> collection=new HashSet<Contact>();
//...
for (Contact contact : this.contacts) {
   collection.add(concat);
}

anyway, if you want use ArrayList:

for (Contact contact : this.contacts) {
   if(!collection.contains(contact){
      collection.add(concat);
   }
}

in both solutions you must override equals method in Contact.class

public boolean equals(Object o){
   if(o == null) return false;
   if(o instanceof Contact){
      Contact c=(Contact)o;
      return c.name.equals(this.name);
   }
   return false;
}

Upvotes: 2

JB Nizet
JB Nizet

Reputation: 692281

First of all, your code doesn't compile: the contactsList variable is not defined anywhere.

Second, your logic is flawed:

    for (Contact contact : this.contacts) {
        if (this.findContact(contactName)) 
            contactsList.add(contact);
    }
    return contactsList;

Let's translate this in English: for each contact, if the list contains contactName, the contact is added to the list. So, if the list contains contact name, all the contacts are added to the list, otherwise, none is added.

What you actually want is a method that finds the contacts in the list which have the given name:

public List<Contact> queryContacts(String contactName) {
    List<Contact> contactsList = new ArrayList<>();
    for (Contact contact : this.contacts) {
        if (contact.equals(contactName)) { 
            contactsList.add(contact);
        }
    }
    return contactsList;
}

Or, with Java 8:

public List<Contact> queryContacts(String contactName) {
    return contacts.stream()
                   .filter(contact -> contact.getName().equals(contactName))
                   .collect(Collectors.toList());
}

Upvotes: 2

Related Questions