0

Suppose I want to store phone numbers of persons. Which kind of collection should I use for key value pairs? And it should be helpful for searching. The name may get repeated, so there may be the same name having different phone numbers.

Sentry
  • 4,102
  • 2
  • 30
  • 38
Sanjay Rabari
  • 2,091
  • 1
  • 17
  • 32

4 Answers4

5

In case you want to use key value pair. Good choice is to use Map instead of collection.

So what should that map store ?

As far it goes for key. First thing you want to assure is that your key is unique to avoid collisions.

class Person {

 long uniqueID; 

 String name; 
 String lastname;

}

So we will use the uniqueID of Person for key.

What about value ?

In this case is harder. As the single Person can have many phone numbers. But for simple task lest assume that a person can have only one phone number. Then what you look is

class PhoneNumberRegistry {

   Map<Long,String> phoneRegistry = new HashMap<>();

}

Where the long is taken from person. When you deal with Maps, you should implement the hashCode and equals methods.

Then your registry could look like

 class PhoneNumberRegistry {

   Map<Person,String> phoneRegistry = new HashMap<>();

}

In case when you want to store more then one number for person, you will need to change the type of value in the map.

You can use Set<String> to store multiple numbers that will not duplicate. But to have full control you should introduce new type that not only store the number but also what king of that number is.

 class PhoneNumberRegistry {

   Map<Person,HashSet<String>> phoneRegistry = new HashMap<>();

}

But then you will have to solve various problems like, what phone number should i return ?

Community
  • 1
  • 1
  • 1
    `Map>`cant be used with `HashMap<>` because `Set` is an interface. – Grim Apr 03 '14 at 10:54
  • @PeterRader, Thanks for that note about `Set`. But i do not understand whats wrong with that it can store nulls? – Damian Leszczyński - Vash Apr 03 '14 at 12:28
  • See, i have no problems with having a person in a Phonebook that has no numbers. If you give back a empty list/map it would be ok for me because it signalize: `hey, i have 0 numbers for this person`, but `null` is questionable! Maybe i dont understand the differece between `null` and `empty list`? In what conditions is `null` better than an empty list? – Grim Apr 03 '14 at 14:27
  • Your thinking is quite good. But if the map does not contain the key it will resolve null. IMHO the storage strucutre should be responsible for logic, that why it is in an class that can mange it. An in case storage do not contain number return empty list null or throw exception. But that is bussiness logic, that do not apply for this case. – Damian Leszczyński - Vash Apr 03 '14 at 14:58
  • Sure, `get` returns `null` if there is a Key or not. But contains() will return `true` so this may cause a NPE: `if(pR.contains(p))for(String no:pR.get(p)){}`. In young years we used `null` for lists that are not yet initialized (it take some time to let developers know its bad practice), state of the art is to use `Collections.emptyList()` and `Collections.emptyMap()`. State of the future art is to use `@Nullable` by the way. – Grim Apr 03 '14 at 17:00
2

Your problem has different solutions. For example, I'll go with a LIST: List<Person>, where Person is a class like this:

public class Person{

    private String name;
    private List<String> phoneNumbers;

    // ...

}

For collections searching/filtering I suggest Guava Collections2.filter method.

davioooh
  • 23,742
  • 39
  • 159
  • 250
1

Maybe

List<Pair<String, String> (for one number per person) or
List<Pair<String, String[]> (for multiple numbers per person)

will fit your needs.

tilpner
  • 4,351
  • 2
  • 22
  • 45
ifloop
  • 8,079
  • 2
  • 26
  • 35
  • 1
    There is no `Pair` in the JDK – fge Apr 03 '14 at 10:33
  • javafx.util.Pair [Javadoc](http://docs.oracle.com/javafx/2/api/javafx/util/Pair.html) – ifloop Apr 03 '14 at 10:34
  • Argh, please don't. It will fail on JREs without javafx. – tilpner Apr 03 '14 at 10:38
  • _As of JDK 7u6 JavaFX is included with the standard JDK and JRE bundles._ From [Oracle.com](http://www.oracle.com/technetwork/java/javafx/downloads/index.html) I highly suggest on uses always the most up to date (and stable) version of the software one is working with. – ifloop Apr 03 '14 at 10:43
  • 1
    Sure, but there are still people using IE6. You can't force the user to run it on a specific JRE. – tilpner Apr 03 '14 at 10:45
  • Also, `Pair` as well as tuples of other languages convey no semantic information. A class `Person` provides abstraction by hiding the representation and clarifies what the data is used for. `Pair` can be anything, `Person` not. – tilpner Apr 03 '14 at 11:00
1

You should use this:

Hashtable<String, ArrayList<String>> addressbook = new Hashtable<>();
ArrayList<String> persons =  new ArrayList<String>()
persons.add("Tom Butterfly");
persons.add("Maria Wanderlust");
addressbook.put("+0490301234567", persons);
addressbook.put("+0490301234560", persons);

Hashtable are save to not have empty elements, the ArrayList is fast in collect small elements. Know that multiple persons with different names may have same numbers.

Know that 2 persons can have the same number and the same Name!

String name = "Tom Butterfly";
String[] array = addressbook.keySet().toArray(new String[] {});
int firstElement = Collections.binarySearch(Arrays.asList(array),
        name, new Comparator<String>() {

            @Override
            public int compare(String top, String bottom) {
                if (addressbook.get(top).contains(bottom)) {
                    return 0;
                }
                return -1;
            }
        });
System.out.println("Number is " + array[firstElement]);
Grim
  • 1,938
  • 10
  • 56
  • 123