-1

I'm starting out on Java and I'm creating a basic phonebook application. I'd like to implement a "Search Contacts" function that searches through an ArrayList of contacts and returns a count of how many contacts match the user-inputted String using a for each loop and if statement. Question is, is it possible to receive a count of the contacts that match the user's search input without first defining an int - say, int counter = 0; - and then updating it within the if statement?

Below is an example of the only method I know could work to tally the number of matching contacts:

int counter = 0;

System.out.println("Please enter name of contact: ");

String nameRequest = scanner.nextLine();


for (Contact c: contactList) {
    if (nameRequest.equals(c.getName())){
    counter++;
    System.out.println(counter + " contact(s) found"
    System.out.println("Name: " + c.getName());
    }
}

Extras: How could I go about so the code also returns contacts that are only a partial match? e.g. User inputs "Michael" but there are no contacts that only contain "Michael". There are however contacts called "Michael B Jordan" and "Michael Schumacher" which I'd like returned for the partial match.

Thanks in advance!

  • A counter variable is pretty much the standard way to do something like this. For partial matches check the String methods `contains`, `startsWith` and `toLowerCase`. – Reto Höhener Jan 10 '21 at 15:22
  • You could also filter the ArrayList (see https://stackoverflow.com/questions/122105/what-is-the-best-way-to-filter-a-java-collection), and then check the length of the filtered list, but beware that these look pretty but may be expensive for larger lists. – user2740650 Jan 10 '21 at 15:25

2 Answers2

1

Using the counter variable it is a standard for people in this cases. But if it is for study purposes, you can achieve this with Lambda, where you first select the contacts, get the names and store in a temporary list:

List<String> contactsFound = contactList.stream()
    .map(Contact::getName)
    .filter(nameRequest::equals)
    .collect(Collectors.toList());

System.out.println(contactsFound.size() + " contact(s) found");

contactsFound.forEach(contactName -> System.out.println("Name: " + contactName));
Brother
  • 2,150
  • 1
  • 20
  • 24
  • 1
    You can replace the filter with `s -> s.toLowerCase().contains(nameRequest.toLowerCase())` to find partial matches (case insensitive). – DarkMatter Jan 10 '21 at 15:35
0

Here is the same basic solution as Brothers answer but with a for loop (as in the question):

List<String> contactsFound = new ArrayList<>();
for (Contact c: contactList) {
    if (c.getName().toLowerCase().contains(nameRequest.toLowerCase())){
        contactsFound.add(c.getName());
    }
}
DarkMatter
  • 1,007
  • 7
  • 13