javaoophashmaphashsetkeyset

Get HashMap key by inputting HashMap value not working as expected


The problem is in the method getName()

public class Phonebook implements PhonebookInterface {

    private Map<String, Set<String>> phonebook;
    private Map<String, Address> address;

    public Phonebook() {
        this.phonebook = new HashMap<String, Set<String>>();
        this.address = new HashMap<String, Address>();
    }

    @Override
    public void addNumber(String person, String number) {
        if (!this.phonebook.containsKey(person)) {
            this.phonebook.put(person, new HashSet<String>());
        }

        this.phonebook.get(person).add(number);
    }

    @Override
    public void getName(String number) {
        for (String person : this.phonebook.keySet()) {
            if (this.phonebook.get(person).contains(number)) {
                System.out.println(" " + person);
            } else {
                System.out.println("  not found");
            }
        }
    }

    @Override
    public void getNumber(String person) {
        try {
            for (String n : this.phonebook.get(person)) {
                if (this.phonebook.get(person).size() > 1) {
                    System.out.println(" " + n);
                } else {
                    System.out.println("number: " + n);
                }
            }
        } catch (Exception e) {
            System.out.println("  not found");
        }
    }

    public void addAddress(String person, String street, String city) {
        this.address.put(person, new Address(street, city));
    }

    public void getInfo(String person) {
        if (this.address.containsKey(person)) {
            System.out.println("  address: " + this.address.get(person));

            if (this.phonebook.containsKey(person)) {
                System.out.println("  phone numbers:");
                for (String n : this.phonebook.get(person)) {
                    System.out.println("  " + n);
                }
            } else {
                System.out.println("  phone number not found");
            }
        } else {
            System.out.println("  not found");
        }
    }

    public void removeInfo(String person) {
        if (this.address.containsKey(person)) {
            this.address.remove(person);
        } else {
            System.out.println(" not found");
        }
    }
}

public class Address {

    private String street;
    private String city;

    public Address() {
    }

    Address(String street, String city) {
        this.street = street;
        this.city = city;
    }

    public String getStreet() {
        return this.street;
    }

    public String getCity() {
        return this.city;
    }

    public String toString() {
        return this.street + " " + this.city;
    }

}

class Main {

    public static void main(String[] args) {
        Phonebook p = new Phonebook();

        System.out.println("Search for number: ");

        System.out.println("Pekka :");
        p.addNumber("Pekka", "014-1234");
        p.addNumber("Pekka", "015-5344");
        p.getNumber("Pekka");

        System.out.println("Matti :");
        p.addNumber("Matti", "013-4321");
        p.getNumber("Matti");

        System.out.println("\nsearch for a person by phone number: ");

        p.getName("013-4321");
        p.getName("1234567");
    }
}

The expected output is:

Search for number:
Pekka :
014-1234
015-5344
Matti :
number: 013-4321

search for a person by phone number:
Matti
not found

But the output was :

Search for number:
Pekka :
014-1234
015-5344
Matti :
number: 013-4321

Search for a person by phone number:
not found
Matti
not found
not found

Why is the output printing "not found" 3 times instead just once?


Solution

  • You iterate over all the keys of the Map and compare the corresponding values to the value you are looking for. When there's no match, you print "not found".

    Your Map has two keys, so if you are searching for a value present in the Map, you'll print the matching key, but you'll also print "not found" for the other key.

    If you are searching for a value not present in the Map, you'll print "not found" twice (once for each key).

    You should only print "not found" after iterating over all the keys:

    public void getName(String number) {   
        for (String person : this.phonebook.keySet()) {   
            if (this.phonebook.get(person).contains(number)) {   
                System.out.println(" " + person);
                return;
            }    
        }
        System.out.println("  not found"); 
    }