How to look at different parameters from an object from within the same method?

Viewed 66

I have a Contact class which has name, email and address. I store them inside an ArrayList. Right now I have three different methods that are used for letting the user search a contact by name, email or address. Each one does exactly the same as the others except for the comparison statement, one has name.equals(contact.getName()), another email.equals(contact.getEmail()) and the last one has address.equals(contact.getAddress()). I am aware of the DRY principle and I think it can be applied here, is there a way to avoid repeating myself in this case?

public void searchName(String name)
{
    for(int i = 0; i < contacts.size(); i++)
    {
      Contact contact = contacts.get(i);

      if(name.equals(contact.getName())
       {
          printContactInfo(contact);
       }
     }
}

The other two methods are exactly the same but instead of using name they use email or address.

2 Answers

You could pass this as a Function. Java 8's syntax enhancements lend themselves nicely to such usecases:

public void searchName(String name) {
    search(name, Contact::getName);
}

public void searchEmail(String email) {
    search(email, Contact::getEmail);
}

public void searchAddress(String address) {
    search(address, Contact::getAddress);
}

private void search(String s, Function<Contact, String> f) {
    contacts.stream().filter(c -> f.apply(c).equals(s)).forEach(this::printContactInfo);
}

Define your three search methods which all delegate to a "master" search method. Implementing the enum needed for this and the actual logic behind the search is an exercise left for the reader.

public void searchName(String name) {
    search(SearchType.NAME, name);
}

public void searchEmail(String email) {
    search(SearchType.EMAIL, email);
}

public void searchAddress(String address) {
    search(SearchType.ADDRESS, address);
}

private void search(SearchType type, String value) {
    switch(type) {
        case NAME:
        break;
        case EMAIL:
        break;
        case ADDRESS:
        break;
    }
}
Related