user1924563
user1924563

Reputation: 41

Associate multiple values with the single key and also maintain the order of values

I have a class which contain the following members

private String patientName;
private String patientPhoneNumber;

now I have multiple names attached with the phone No. for example

1234567, AAA
1234567, BBB
8765432, CCC
8765432, GGG

Now I want to store them in a Map but the phone No. should be the key having multiple values, for 1234567 i should have value AAA and BBB, please advise how can I store the multiple values with the single key in map here my key is Phone No. and then please let me know if I want to print in console then ow would I iterate over the Map

Also please not that I want to maintain the order also let say first I get the value AAA and then BBB so i should maintain these order also, since I get this is just a example but in my scenario I will be getting this value from backend so to maintain the order is also necessary please advise.

Upvotes: 1

Views: 1707

Answers (7)

Alekya
Alekya

Reputation: 243

public static void main(String[] args) {

      Map<Integer,List<String>> map = new HashMap<Integer,List<String>>();

        //insert values into list one
        List<String> list1 = new ArrayList<String>();
        list1.add("AAA");
        list1.add("BBB");

        //insert values into list one
        List<String> list2 = new ArrayList<String>();
        list2.add("CCC");
        list2.add("GGG");

        //insert values to keys
        //single key multiple values
        map.put(1234567, list1);
        map.put(8765432, list2);

        //iterating and displaying the values
        for(Map.Entry<Integer,List<String>> entry: map.entrySet() ) {

            Integer key = entry.getKey();
            List<String> values = entry.getValue();
            System.out.println("Value of " +key+ " is " +values);
            //System.out.println("Value of " +key+ " is " +values.get(0));
            //System.out.println("Value of " +key+ " is " +values.get(1));

        }
}

Upvotes: 0

Miserable Variable
Miserable Variable

Reputation: 28752

Associate multiple values with the single key

That is a Multimap:

A collection similar to a Map, but which may associate multiple values with a single key.

LinkedHashMultimap from Google Collections seems to fit the bill:

Implementation of Multimap that does not allow duplicate key-value entries and that returns collections whose iterators follow the ordering in which the data was added to the multimap.

If you don't want to add the dependency, you can use a collection as value type:

Map<String /*number*/, List<String> /*names*/> numbers;

Note that the former only allows retrieval in order of insertion, if you want to be able to change it you will have to use the latter hand-rolled solution

Upvotes: 1

Yanick Rochon
Yanick Rochon

Reputation: 53521

Use a LinkedHashMap and an ArrayList for each values :

LinkedHashMap<String,ArrayList<String>> phoneNumbers = new LinkedHashMap<String,ArrayList<String>>();

// register new phone number
phoneNumbers.put("1234567", new ArrayList<String>());

// add names to the phone number
phoneNumbers.get("1234567").add("AAA");
phoneNumbers.get("1234567").add("BBB");

Both collections preserve the insertion ordering.

** Edit **

Here, this is roughly what you'd need (this was done on the spot without much testing, but you should get the idea). Since your ordering may vary, I thought limiting duplicates and providing a comparator for ordering should be preferable (as suggested by other answers) :

public class LinkedMultiMap<K,V> {

    private Comparator<V> comparator;
    private LinkedHashMap<K,Set<V>> entries;

    public LinkedMultiMap() {
        this(null);
    }

    public LinkedMultiMap(Comparator<V> comparator) {
        this.comparator = comparator;
        this.entries = new LinkedHashMap<K, Set<V>>();
    }

    public boolean add(K key, V value) {
        if (!entries.containsKey(key)) {
            entries.put(key, new TreeSet<V>(comparator));
        }

        return entries.get(key).add(value);
    }

    public Collection<V> get(K key) {
        return entries.get(key);
    }

    public boolean remove(K key, V value) {
        boolean removed = false;
        if (entries.containsKey(key)) {
            removed = entries.get(key).remove(value);

            if (entries.get(key).isEmpty()) {
                entries.remove(key);
            }
        }
        return removed;
    }

    public Collection<V> removeAll(K key) {
        return entries.remove(key);
    }

    public Iterator<K> keyIterator() {
        return entries.keySet().iterator();
    }
}

Upvotes: 1

Mordechai
Mordechai

Reputation: 16184

new Map<String, TreeSet<String>>()

Will allow you to store the values in a TreeSet (sorted...).

To print them:

for(Map.Entry entry : phoneBook.entries()){
    System.out.println(entry.key() + ":");
    TreeSet names = entry.value();
    for(String name : names){
        System.out.println("\t" + name);
    }
}

You can add, like this, if you want case insensitive ordering:

TreeSet<String> nameSet = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
phoneBook.add(number, nameSet);

Upvotes: 2

BevynQ
BevynQ

Reputation: 8259

private Map<String,List<String>> patients;

public void setPatientNumber(String number, String patient){
    List<String> list = patients.get(number);
    if(list == null){
        list = new ArrayList<String>();
        patients.put(number,list);
    }
    list.add(patient);
}

Upvotes: 2

Helio Santos
Helio Santos

Reputation: 6805

You may try something like this:

HashMap<String,LinkedList<String>> map

Upvotes: 2

Brent Worden
Brent Worden

Reputation: 10974

Use a Map to store your data. The keys should be String objects and the values should be List objects. Using a List as the map entry value allows to associate multiple values with a single key. A List will also maintain the order of adding elements.

Upvotes: 0

Related Questions